public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] rust-constexpr.cc: port over more cases to eval_constant_expression
@ 2022-08-29 15:34 Thomas Schwinge
  0 siblings, 0 replies; 2+ messages in thread
From: Thomas Schwinge @ 2022-08-29 15:34 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a38ad0b614ff5d601e5425824ad760235710eee5

commit a38ad0b614ff5d601e5425824ad760235710eee5
Author: Faisal Abbas <90.abbasfaisal@gmail.com>
Date:   Sat Aug 6 21:32:41 2022 +0100

    rust-constexpr.cc: port over more cases to eval_constant_expression

Diff:
---
 gcc/rust/backend/rust-constexpr.cc | 46 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index 276bfe94e6f..340960e0ab6 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -1398,6 +1398,32 @@ eval_bare_aggregate (const constexpr_ctx *ctx, tree t, bool lval,
   return t;
 }
 
+/* Subroutine of cxx_eval_constant_expression.
+   Like cxx_eval_unary_expression, except for trinary expressions.  */
+
+static tree
+cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t, bool lval,
+			     bool *non_constant_p, bool *overflow_p)
+{
+  int i;
+  tree args[3];
+  tree val;
+
+  for (i = 0; i < 3; i++)
+    {
+      args[i] = eval_constant_expression (ctx, TREE_OPERAND (t, i), lval,
+					  non_constant_p, overflow_p);
+      VERIFY_CONSTANT (args[i]);
+    }
+
+  val = fold_ternary_loc (EXPR_LOCATION (t), TREE_CODE (t), TREE_TYPE (t),
+			  args[0], args[1], args[2]);
+  if (val == NULL_TREE)
+    return t;
+  VERIFY_CONSTANT (val);
+  return val;
+}
+
 /* Return true if T is a valid constant initializer.  If a CONSTRUCTOR
    initializes all the members, the CONSTRUCTOR_NO_CLEARING flag will be
    cleared.
@@ -1649,6 +1675,11 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
       r = rs_eval_indirect_ref (ctx, t, lval, non_constant_p, overflow_p);
       break;
 
+    case VEC_PERM_EXPR:
+      r = cxx_eval_trinary_expression (ctx, t, lval, non_constant_p,
+				       overflow_p);
+      break;
+
     case PAREN_EXPR:
       gcc_assert (!REF_PARENTHESIZED_P (t));
       /* A PAREN_EXPR resulting from __builtin_assoc_barrier has no effect in
@@ -1680,6 +1711,21 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
       return eval_constant_expression (ctx, BIND_EXPR_BODY (t), lval,
 				       non_constant_p, overflow_p, jump_target);
 
+    case OBJ_TYPE_REF:
+      /* Virtual function lookup.  We don't need to do anything fancy.  */
+      return eval_constant_expression (ctx, OBJ_TYPE_REF_EXPR (t), lval,
+				       non_constant_p, overflow_p);
+
+      case EXIT_EXPR: {
+	tree cond = TREE_OPERAND (t, 0);
+	cond = eval_constant_expression (ctx, cond, /*lval*/ false,
+					 non_constant_p, overflow_p);
+	VERIFY_CONSTANT (cond);
+	if (integer_nonzerop (cond))
+	  *jump_target = t;
+      }
+      break;
+
     case RESULT_DECL:
       if (lval)
 	return t;

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [gcc/devel/rust/master] rust-constexpr.cc: port over more cases to eval_constant_expression
@ 2022-08-29 15:34 Thomas Schwinge
  0 siblings, 0 replies; 2+ messages in thread
From: Thomas Schwinge @ 2022-08-29 15:34 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:bd31c63fe15c4e39d3036ff7adcd22eadd6b53ea

commit bd31c63fe15c4e39d3036ff7adcd22eadd6b53ea
Author: Faisal Abbas <90.abbasfaisal@gmail.com>
Date:   Mon Aug 8 12:09:44 2022 +0100

    rust-constexpr.cc: port over more cases to eval_constant_expression

Diff:
---
 gcc/rust/backend/rust-constexpr.cc | 132 ++++++++++++++++++++++++++++++++-----
 gcc/rust/backend/rust-tree.h       |   5 ++
 2 files changed, 122 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index 340960e0ab6..df4ceba4f7a 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -1514,6 +1514,21 @@ reduced_constant_expression_p (tree t)
     }
 }
 
+/* TEMP is the constant value of a temporary object of type TYPE.  Adjust
+   the type of the value to match.  */
+
+static tree
+adjust_temp_type (tree type, tree temp)
+{
+  if (same_type_p (TREE_TYPE (temp), type))
+    return temp;
+
+  gcc_assert (scalarish_type_p (type));
+  /* Now we know we're dealing with a scalar, and a prvalue of non-class
+     type is cv-unqualified.  */
+  return fold_convert (cv_unqualified (type), temp);
+}
+
 static tree
 eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
 			  bool *non_constant_p, bool *overflow_p,
@@ -1544,6 +1559,7 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
       return t;
     }
 
+  constexpr_ctx new_ctx;
   tree r = t;
   tree_code tcode = TREE_CODE (t);
   switch (tcode)
@@ -1561,6 +1577,14 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
       }
       break;
 
+    case VAR_DECL:
+      if (DECL_HAS_VALUE_EXPR_P (t))
+	{
+	  r = DECL_VALUE_EXPR (t);
+	  return eval_constant_expression (ctx, r, lval, non_constant_p,
+					   overflow_p);
+	}
+
     case PARM_DECL:
       if (lval && !TYPE_REF_P (TREE_TYPE (t)))
 	/* glvalue use.  */;
@@ -1643,6 +1667,67 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
 				   overflow_p);
       break;
 
+      case TARGET_EXPR: {
+	tree type = TREE_TYPE (t);
+
+	if (!literal_type_p (type))
+	  {
+	    if (!ctx->quiet)
+	      {
+		auto_diagnostic_group d;
+		error ("temporary of non-literal type %qT in a "
+		       "constant expression",
+		       type);
+		// explain_non_literal_class (type);
+	      }
+	    *non_constant_p = true;
+	    break;
+	  }
+	gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (t));
+	/* Avoid evaluating a TARGET_EXPR more than once.  */
+	tree slot = TARGET_EXPR_SLOT (t);
+	if (tree *p = ctx->global->values.get (slot))
+	  {
+	    if (lval)
+	      return slot;
+	    r = *p;
+	    break;
+	  }
+	if ((AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
+	  {
+	    /* We're being expanded without an explicit target, so start
+	       initializing a new object; expansion with an explicit target
+	       strips the TARGET_EXPR before we get here.  */
+	    new_ctx = *ctx;
+	    /* Link CTX to NEW_CTX so that lookup_placeholder can resolve
+	       any PLACEHOLDER_EXPR within the initializer that refers to the
+	       former object under construction.  */
+	    new_ctx.parent = ctx;
+	    new_ctx.ctor = build_constructor (type, NULL);
+	    CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
+	    new_ctx.object = slot;
+	    ctx->global->values.put (new_ctx.object, new_ctx.ctor);
+	    ctx = &new_ctx;
+	  }
+	/* Pass false for 'lval' because this indicates
+	   initialization of a temporary.  */
+	r = eval_constant_expression (ctx, TREE_OPERAND (t, 1), false,
+				      non_constant_p, overflow_p);
+	if (*non_constant_p)
+	  break;
+	/* Adjust the type of the result to the type of the temporary.  */
+	r = adjust_temp_type (type, r);
+	if (TARGET_EXPR_CLEANUP (t) && !CLEANUP_EH_ONLY (t))
+	  ctx->global->cleanups->safe_push (TARGET_EXPR_CLEANUP (t));
+	r = unshare_constructor (r);
+	ctx->global->values.put (slot, r);
+	if (ctx->save_exprs)
+	  ctx->save_exprs->safe_push (slot);
+	if (lval)
+	  return slot;
+      }
+      break;
+
     case CALL_EXPR:
       r = eval_call_expression (ctx, t, false, non_constant_p, overflow_p);
       break;
@@ -1667,6 +1752,38 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
 	}
       break;
 
+      case DECL_EXPR: {
+	r = DECL_EXPR_DECL (t);
+
+	if (AGGREGATE_TYPE_P (TREE_TYPE (r)) || VECTOR_TYPE_P (TREE_TYPE (r)))
+	  {
+	    new_ctx = *ctx;
+	    new_ctx.object = r;
+	    new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL);
+	    CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
+	    ctx->global->values.put (r, new_ctx.ctor);
+	    ctx = &new_ctx;
+	  }
+
+	if (tree init = DECL_INITIAL (r))
+	  {
+	    init = eval_constant_expression (ctx, init, false, non_constant_p,
+					     overflow_p);
+	    /* Don't share a CONSTRUCTOR that might be changed.  */
+	    init = unshare_constructor (init);
+	    /* Remember that a constant object's constructor has already
+	       run.  */
+	    if (CLASS_TYPE_P (TREE_TYPE (r)) && RS_TYPE_CONST_P (TREE_TYPE (r)))
+	      TREE_READONLY (init) = true;
+	    ctx->global->values.put (r, init);
+	  }
+	else if (ctx == &new_ctx)
+	  /* We gave it a CONSTRUCTOR above.  */;
+	else
+	  ctx->global->values.put (r, NULL_TREE);
+      }
+      break;
+
     /* These differ from cxx_eval_unary_expression in that this doesn't
 	 check for a constant operand or result; an address can be
 	 constant without its operand being, and vice versa.  */
@@ -2526,21 +2643,6 @@ eval_binary_expression (const constexpr_ctx *ctx, tree t, bool lval,
   return fold_binary_loc (loc, code, type, lhs, rhs);
 }
 
-/* TEMP is the constant value of a temporary object of type TYPE.  Adjust
-   the type of the value to match.  */
-
-static tree
-adjust_temp_type (tree type, tree temp)
-{
-  if (same_type_p (TREE_TYPE (temp), type))
-    return temp;
-
-  gcc_assert (scalarish_type_p (type));
-  /* Now we know we're dealing with a scalar, and a prvalue of non-class
-     type is cv-unqualified.  */
-  return fold_convert (cv_unqualified (type), temp);
-}
-
 /* Helper function of cxx_bind_parameters_in_call.  Return non-NULL
    if *TP is address of a static variable (or part of it) currently being
    constructed or of a heap artificial variable.  */
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index bd11b20e77f..9efa4096bf6 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -1274,6 +1274,11 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
 
 #define AGGR_INIT_EXPR_SLOT(NODE) TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 2)
 
+/* True if this TARGET_EXPR expresses direct-initialization of an object
+   to be named later.  */
+#define TARGET_EXPR_DIRECT_INIT_P(NODE)                                        \
+  TREE_LANG_FLAG_2 (TARGET_EXPR_CHECK (NODE))
+
 #if defined ENABLE_TREE_CHECKING
 
 #define LANG_DECL_MIN_CHECK(NODE)                                              \

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-08-29 15:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-29 15:34 [gcc/devel/rust/master] rust-constexpr.cc: port over more cases to eval_constant_expression Thomas Schwinge
2022-08-29 15:34 Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).