https://gcc.gnu.org/g:e7523a40cb1787d52a638cf8a4f9eeb5212f770f

commit r16-56-ge7523a40cb1787d52a638cf8a4f9eeb5212f770f
Author: Jason Merrill <ja...@redhat.com>
Date:   Sun Apr 20 12:31:35 2025 -0400

    c++: new size folding [PR118775]
    
    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.

Diff:
---
 gcc/cp/constexpr.cc                          | 10 ++++++----
 gcc/cp/init.cc                               |  4 ++--
 gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C |  4 ++--
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index be73e707aaf4..79b7d02f8770 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -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;
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index e589e45e8916..062a4938a44c 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -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.  */
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C 
b/gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C
index ee62f18922c5..17c9f548d987 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C
@@ -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;
 }

Reply via email to