diff options
author | Jason Merrill <jason@redhat.com> | 2025-04-20 12:31:35 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2025-04-21 15:50:21 -0400 |
commit | e7523a40cb1787d52a638cf8a4f9eeb5212f770f (patch) | |
tree | f71c3f1d50fceb1fe92bd5b661ba7117cebc9417 /gcc | |
parent | e6ae0de72ef696c4016cc66c53a4aa49a1e900a6 (diff) | |
download | gcc-e7523a40cb1787d52a638cf8a4f9eeb5212f770f.zip gcc-e7523a40cb1787d52a638cf8a4f9eeb5212f770f.tar.gz gcc-e7523a40cb1787d52a638cf8a4f9eeb5212f770f.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/constexpr.cc | 10 | ||||
-rw-r--r-- | gcc/cp/init.cc | 4 | ||||
-rw-r--r-- | 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 be73e70..79b7d02 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 e589e45..062a493 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 ee62f18..17c9f54 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; } |