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; }