aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2025-03-11 11:16:26 -0400
committerJason Merrill <jason@redhat.com>2025-04-21 15:54:44 -0400
commit9ac98b5742ebce41d7da9fda10852a0bc958f1cb (patch)
treee22e49cd095350380f39b95cccf4e9b07e2835e0 /gcc
parente7523a40cb1787d52a638cf8a4f9eeb5212f770f (diff)
downloadgcc-9ac98b5742ebce41d7da9fda10852a0bc958f1cb.zip
gcc-9ac98b5742ebce41d7da9fda10852a0bc958f1cb.tar.gz
gcc-9ac98b5742ebce41d7da9fda10852a0bc958f1cb.tar.bz2
c++: reorder constexpr checks
My proposed change to stop setting TREE_STATIC on constexpr heap pseudo-variables led to a diagnostic regression because we would get the generic "not constant" diagnostic before the "allocated storage" diagnostic. So let's move the generic verify_constant down a bit. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): Move verify_constant later.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/constexpr.cc37
1 files changed, 21 insertions, 16 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 79b7d02..8a11e62 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -9227,11 +9227,6 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
if (r == void_node && !constexpr_dtor && ctx.ctor)
r = ctx.ctor;
- if (!constexpr_dtor)
- verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
- else
- DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = true;
-
unsigned int i;
tree cleanup;
/* Evaluate the cleanups. */
@@ -9250,15 +9245,6 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
non_constant_p = true;
}
- if (TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r))
- {
- if (!allow_non_constant)
- error ("%qE is not a constant expression because it refers to "
- "an incompletely initialized variable", t);
- TREE_CONSTANT (r) = false;
- non_constant_p = true;
- }
-
if (!non_constant_p && cxx_dialect >= cxx20
&& !global_ctx.heap_vars.is_empty ())
{
@@ -9315,6 +9301,21 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
non_constant_p = true;
}
+ if (!non_constant_p && !constexpr_dtor)
+ verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
+
+ /* After verify_constant because reduced_constant_expression_p can unset
+ CONSTRUCTOR_NO_CLEARING. */
+ if (!non_constant_p
+ && TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r))
+ {
+ if (!allow_non_constant)
+ error ("%qE is not a constant expression because it refers to "
+ "an incompletely initialized variable", t);
+ TREE_CONSTANT (r) = false;
+ non_constant_p = true;
+ }
+
if (non_constant_p)
/* If we saw something bad, go back to our argument. The wrapping below is
only for the cases of TREE_CONSTANT argument or overflow. */
@@ -9331,13 +9332,17 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
if (non_constant_p && !allow_non_constant)
return error_mark_node;
- else if (constexpr_dtor)
- return r;
else if (non_constant_p && TREE_CONSTANT (r))
r = mark_non_constant (r);
else if (non_constant_p)
return t;
+ if (constexpr_dtor)
+ {
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = true;
+ return r;
+ }
+
/* Check we are not trying to return the wrong type. */
if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (r)))
{