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).