aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2023-12-12 22:53:10 -0500
committerJason Merrill <jason@redhat.com>2023-12-13 11:25:19 -0500
commit958940eb3511e341e57606f5a2f5399bc89533cb (patch)
treed831802c51130510adbc9d27d31787f7be55c02a /gcc/cp/constexpr.cc
parent52b4b7d7f5c7c09f5aaf3934978de9702d8c214b (diff)
downloadgcc-958940eb3511e341e57606f5a2f5399bc89533cb.zip
gcc-958940eb3511e341e57606f5a2f5399bc89533cb.tar.gz
gcc-958940eb3511e341e57606f5a2f5399bc89533cb.tar.bz2
c++: constant direct-initialization [PR108243]
When testing the proposed patch for PR71093 I noticed that it changed the diagnostic for consteval-prop6.C. I then noticed that the diagnostic wasn't very helpful either way; it was complaining about modification of the 'x' variable, but it's not a problem to initialize a local variable with a consteval constructor as long as the value is actually constant, we want to know why the value isn't constant. And then it turned out that this also fixed a missed-optimization bug in the testsuite. PR c++/108243 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): Turn a constructor CALL_EXPR into a TARGET_EXPR. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/consteval-prop6.C: Adjust diagnostic. * g++.dg/opt/is_constant_evaluated3.C: Remove xfails.
Diffstat (limited to 'gcc/cp/constexpr.cc')
-rw-r--r--gcc/cp/constexpr.cc16
1 files changed, 15 insertions, 1 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 58187a4..4cf9dd7 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -8651,7 +8651,21 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
}
if (!object)
{
- if (TREE_CODE (t) == TARGET_EXPR)
+ if (TREE_CODE (t) == CALL_EXPR)
+ {
+ /* If T is calling a constructor to initialize an object, reframe
+ it as an AGGR_INIT_EXPR to avoid trying to modify an object
+ from outside the constant evaluation, which will fail even if
+ the value is actually constant (is_constant_evaluated3.C). */
+ tree fn = cp_get_callee_fndecl_nofold (t);
+ if (fn && DECL_CONSTRUCTOR_P (fn))
+ {
+ object = CALL_EXPR_ARG (t, 0);
+ object = build_fold_indirect_ref (object);
+ r = build_aggr_init_expr (type, r);
+ }
+ }
+ else if (TREE_CODE (t) == TARGET_EXPR)
object = TARGET_EXPR_SLOT (t);
else if (TREE_CODE (t) == AGGR_INIT_EXPR)
object = AGGR_INIT_EXPR_SLOT (t);