c++: constinit and value-initialization [PR119652]
Value-initialization built an AGGR_INIT_EXPR to set AGGR_INIT_ZERO_FIRST on. Passing that AGGR_INIT_EXPR to maybe_constant_value returned a TARGET_EXPR, which potential_constant_expression_1 mistook for a temporary. We shouldn't add a TARGET_EXPR to the AGGR_INIT_EXPR in this case, just like we already avoid adding it to CONSTRUCTOR or CALL_EXPR. PR c++/119652 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): Also don't add a TARGET_EXPR around AGGR_INIT_EXPR. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constinit20.C: New test.
This commit is contained in:
parent
3a77a567b1
commit
c7dc9b6f88
2 changed files with 20 additions and 1 deletions
|
@ -9316,7 +9316,8 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
|
|||
if (TREE_CODE (t) == TARGET_EXPR
|
||||
&& TARGET_EXPR_INITIAL (t) == r)
|
||||
return t;
|
||||
else if (TREE_CODE (t) == CONSTRUCTOR || TREE_CODE (t) == CALL_EXPR)
|
||||
else if (TREE_CODE (t) == CONSTRUCTOR || TREE_CODE (t) == CALL_EXPR
|
||||
|| TREE_CODE (t) == AGGR_INIT_EXPR)
|
||||
/* Don't add a TARGET_EXPR if our argument didn't have one. */;
|
||||
else if (TREE_CODE (t) == TARGET_EXPR && TARGET_EXPR_CLEANUP (t))
|
||||
r = get_target_expr (r);
|
||||
|
|
18
gcc/testsuite/g++.dg/cpp2a/constinit20.C
Normal file
18
gcc/testsuite/g++.dg/cpp2a/constinit20.C
Normal file
|
@ -0,0 +1,18 @@
|
|||
// PR c++/119652
|
||||
// { dg-do compile { target c++20 } }
|
||||
|
||||
struct __shared_count {
|
||||
constexpr __shared_count() {}
|
||||
~__shared_count();
|
||||
int _M_pi = 0;
|
||||
};
|
||||
struct shared_ptr {
|
||||
__shared_count _M_refcount;
|
||||
};
|
||||
struct A {
|
||||
A() = default;
|
||||
shared_ptr m;
|
||||
};
|
||||
constinit A a;
|
||||
constinit A b {};
|
||||
constinit A c = {};
|
Loading…
Add table
Reference in a new issue