aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/constexpr.cc12
-rw-r--r--gcc/cp/typeck2.cc55
-rw-r--r--gcc/testsuite/g++.dg/DRs/dr2543.C5
3 files changed, 48 insertions, 24 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 7b80906..8f7f0b7 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -8448,6 +8448,17 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
}
}
+ if (TREE_CODE (t) == TARGET_EXPR
+ && TREE_CODE (r) == TARGET_EXPR)
+ {
+ /* Preserve this flag for potential_constant_expression, and the others
+ for good measure. */
+ TARGET_EXPR_ELIDING_P (r) = TARGET_EXPR_ELIDING_P (t);
+ TARGET_EXPR_IMPLICIT_P (r) = TARGET_EXPR_IMPLICIT_P (t);
+ TARGET_EXPR_LIST_INIT_P (r) = TARGET_EXPR_LIST_INIT_P (t);
+ TARGET_EXPR_DIRECT_INIT_P (r) = TARGET_EXPR_DIRECT_INIT_P (t);
+ }
+
/* Remember the original location if that wouldn't need a wrapper. */
if (location_t loc = EXPR_LOCATION (t))
protected_set_expr_location (r, loc);
@@ -9774,6 +9785,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case TARGET_EXPR:
if (!TARGET_EXPR_DIRECT_INIT_P (t)
+ && !TARGET_EXPR_ELIDING_P (t)
&& !literal_type_p (TREE_TYPE (t)))
{
if (flags & tf_error)
diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index bf03967..f5cc7c8 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -843,23 +843,45 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
bool const_init;
tree oldval = value;
if (DECL_DECLARED_CONSTEXPR_P (decl)
+ || DECL_DECLARED_CONSTINIT_P (decl)
|| (DECL_IN_AGGR_P (decl)
&& DECL_INITIALIZED_IN_CLASS_P (decl)))
{
value = fold_non_dependent_expr (value, tf_warning_or_error,
/*manifestly_const_eval=*/true,
decl);
+ if (value == error_mark_node)
+ ;
/* Diagnose a non-constant initializer for constexpr variable or
non-inline in-class-initialized static data member. */
- if (!require_constant_expression (value))
- value = error_mark_node;
- else if (processing_template_decl)
- /* In a template we might not have done the necessary
- transformations to make value actually constant,
- e.g. extend_ref_init_temps. */
- value = maybe_constant_init (value, decl, true);
+ else if (!is_constant_expression (value))
+ {
+ /* Maybe we want to give this message for constexpr variables as
+ well, but that will mean a lot of testsuite adjustment. */
+ if (DECL_DECLARED_CONSTINIT_P (decl))
+ error_at (location_of (decl),
+ "%<constinit%> variable %qD does not have a "
+ "constant initializer", decl);
+ require_constant_expression (value);
+ value = error_mark_node;
+ }
else
- value = cxx_constant_init (value, decl);
+ {
+ value = maybe_constant_init (value, decl, true);
+
+ /* In a template we might not have done the necessary
+ transformations to make value actually constant,
+ e.g. extend_ref_init_temps. */
+ if (!processing_template_decl
+ && !TREE_CONSTANT (value))
+ {
+ if (DECL_DECLARED_CONSTINIT_P (decl))
+ error_at (location_of (decl),
+ "%<constinit%> variable %qD does not have a "
+ "constant initializer", decl);
+ value = cxx_constant_init (value, decl);
+ }
+ }
}
else
value = fold_non_dependent_init (value, tf_warning_or_error,
@@ -875,22 +897,7 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
if (!TYPE_REF_P (type))
TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl);
if (!const_init)
- {
- /* [dcl.constinit]/2 "If a variable declared with the constinit
- specifier has dynamic initialization, the program is
- ill-formed." */
- if (DECL_DECLARED_CONSTINIT_P (decl))
- {
- error_at (location_of (decl),
- "%<constinit%> variable %qD does not have a constant "
- "initializer", decl);
- if (require_constant_expression (value))
- cxx_constant_init (value, decl);
- value = error_mark_node;
- }
- else
- value = oldval;
- }
+ value = oldval;
}
/* Don't fold initializers of automatic variables in constexpr functions,
that might fold away something that needs to be diagnosed at constexpr
diff --git a/gcc/testsuite/g++.dg/DRs/dr2543.C b/gcc/testsuite/g++.dg/DRs/dr2543.C
new file mode 100644
index 0000000..87512d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2543.C
@@ -0,0 +1,5 @@
+// CWG 2543
+// { dg-do compile { target c++20 } }
+
+float f;
+constinit int * pi = (int*) &f; // { dg-error "constant" } reinterpret_cast, not constant-initialized