diff options
-rw-r--r-- | gcc/cp/constexpr.cc | 12 | ||||
-rw-r--r-- | gcc/cp/typeck2.cc | 55 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/DRs/dr2543.C | 5 |
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 |