]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: constant direct-initialization [PR108243]
authorJason Merrill <jason@redhat.com>
Wed, 13 Dec 2023 03:53:10 +0000 (22:53 -0500)
committerJason Merrill <jason@redhat.com>
Wed, 13 Dec 2023 16:25:19 +0000 (11:25 -0500)
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.

gcc/cp/constexpr.cc
gcc/testsuite/g++.dg/cpp2a/consteval-prop6.C
gcc/testsuite/g++.dg/opt/is_constant_evaluated3.C

index 58187a4fd1209711ffa73974b8e7682dbd3d3c95..4cf9dd71b053156b5e46a00a8c94c0167fb6f116 100644 (file)
@@ -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);
index 93ed398d9bf5e55f6d693fa8d8a2d53de45c11ce..ca7db7c63d37e08eb13a507bfc4ccc66ece3c90c 100644 (file)
@@ -48,7 +48,7 @@ struct X {
   int a = sizeof(undef(0));
   int x = undef(0);
 
-  X() = default; // { dg-error "modification of .x. is not a constant expression" }
+  X() = default; // { dg-error {'consteval int undef\(int\)' used before its definition} }
 };
 
 void
index 0a1e46e5638d78944dbfb06bcfc1f85876575af6..783127cf909b07c8e11c49ccac625fe329ece8f7 100644 (file)
@@ -17,7 +17,7 @@ int main() {
 }
 
 // { dg-final { scan-tree-dump "a1 = {\\.n=42, \\.m=0}" "original" } }
-// { dg-final { scan-tree-dump "a2 = {\\.n=42, \\.m=0}" "original" { xfail *-*-* } } }
-// { dg-final { scan-tree-dump "a3 = {\\.n=42, \\.m=0}" "original" { xfail *-*-* } } }
-// { dg-final { scan-tree-dump "a4 = {\\.n=42, \\.m=0}" "original" { xfail *-*-* } } }
-// { dg-final { scan-tree-dump "a5 = {\\.n=42, \\.m=0}" "original" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "a2 = {\\.n=42, \\.m=0}" "original" } }
+// { dg-final { scan-tree-dump "a3 = {\\.n=42, \\.m=0}" "original" } }
+// { dg-final { scan-tree-dump "a4 = {\\.n=42, \\.m=0}" "original" } }
+// { dg-final { scan-tree-dump "a5 = {\\.n=42, \\.m=0}" "original" } }