aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2025-04-20 12:31:35 -0400
committerJason Merrill <jason@redhat.com>2025-04-21 15:50:21 -0400
commite7523a40cb1787d52a638cf8a4f9eeb5212f770f (patch)
treef71c3f1d50fceb1fe92bd5b661ba7117cebc9417 /gcc
parente6ae0de72ef696c4016cc66c53a4aa49a1e900a6 (diff)
downloadgcc-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.cc10
-rw-r--r--gcc/cp/init.cc4
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C4
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;
}