diff options
author | Jason Merrill <jason@redhat.com> | 2023-12-12 22:53:10 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2023-12-13 11:25:19 -0500 |
commit | 958940eb3511e341e57606f5a2f5399bc89533cb (patch) | |
tree | d831802c51130510adbc9d27d31787f7be55c02a /gcc/cp/constexpr.cc | |
parent | 52b4b7d7f5c7c09f5aaf3934978de9702d8c214b (diff) | |
download | gcc-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.cc | 16 |
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); |