]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: new size folding [PR118775]
authorJason Merrill <jason@redhat.com>
Sun, 20 Apr 2025 16:31:35 +0000 (12:31 -0400)
committerJason Merrill <jason@redhat.com>
Mon, 21 Apr 2025 19:50:21 +0000 (15:50 -0400)
r15-7893 added a workaround for a case where we weren't registering (long)&a
as invalid in a constant-expression, because build_new_1 had folded away the
CONVERT_EXPR that we rely on to diagnose that problem.  In general we want
to defer most folding until cp_fold_function, so let's fold less here.  We
mainly want to expose constant size so we can treat it differently, and we
already did any constexpr evaluation when initializing cst_outer_nelts, so
fold_to_constant seems like the right choice.

PR c++/118775

gcc/cp/ChangeLog:

* constexpr.cc (cxx_eval_call_expression): Add assert.
(fold_to_constant): Handle processing_template_decl.
* init.cc (build_new_1): Use fold_to_constant.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/constexpr-new24.C: Adjust diagnostic.

gcc/cp/constexpr.cc
gcc/cp/init.cc
gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C

index be73e707aaf40347a9cc5700003c766e7f0f2aa3..79b7d02f8770506186418b84ba3591ccc4c1190c 100644 (file)
@@ -2956,12 +2956,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
          gcc_assert (arg0);
          if (new_op_p)
            {
-             /* FIXME: We should not get here; the VERIFY_CONSTANT above
-                should have already caught it.  But currently a conversion
-                from pointer type to arithmetic type is only considered
-                non-constant for CONVERT_EXPRs, not NOP_EXPRs.  */
              if (!tree_fits_uhwi_p (arg0))
                {
+                 /* We should not get here; the VERIFY_CONSTANT above
+                    should have already caught it.  */
+                 gcc_checking_assert (false);
                  if (!ctx->quiet)
                    error_at (loc, "cannot allocate array: size not constant");
                  *non_constant_p = true;
@@ -9490,6 +9489,9 @@ fold_simple (tree t)
 tree
 fold_to_constant (tree t)
 {
+  if (processing_template_decl)
+    return t;
+
   tree r = fold (t);
   if (CONSTANT_CLASS_P (r) && !TREE_OVERFLOW (r))
     return r;
index e589e45e8916abed596b42282a0326e3b3c3a804..062a4938a44c7e63277f3ccdbd58af390d02d18b 100644 (file)
@@ -3405,7 +3405,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
        errval = throw_bad_array_new_length ();
       if (outer_nelts_check != NULL_TREE)
        size = build3 (COND_EXPR, sizetype, outer_nelts_check, size, errval);
-      size = cp_fully_fold (size);
+      size = fold_to_constant (size);
       /* Create the argument list.  */
       vec_safe_insert (*placement, 0, size);
       /* Do name-lookup to find the appropriate operator.  */
@@ -3462,7 +3462,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
            outer_nelts_check = NULL_TREE;
        }
 
-      size = cp_fully_fold (size);
+      size = fold_to_constant (size);
       /* If size is zero e.g. due to type having zero size, try to
         preserve outer_nelts for constant expression evaluation
         purposes.  */
index ee62f18922c58e53472488856683def5fe4cd415..17c9f548d98738f5ddf581c72b82d98afad39dbb 100644 (file)
@@ -6,14 +6,14 @@ int a;
 constexpr char *
 f1 ()
 {
-  constexpr auto p = new char[(long int) &a]; // { dg-error "size not constant" }
+  constexpr auto p = new char[(long int) &a]; // { dg-error "conversion from pointer" }
   return p;
 }
 
 constexpr char *
 f2 ()
 {
-  auto p = new char[(long int) &a];  // { dg-error "size not constant" }
+  auto p = new char[(long int) &a];  // { dg-error "conversion from pointer" }
   return p;
 }