diff options
author | Jason Merrill <jason@redhat.com> | 2022-06-01 16:13:48 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2022-06-02 15:15:26 -0400 |
commit | db4243bb681f7d4e82c15674eb3bfd9b82b0cf71 (patch) | |
tree | 37a403616ad4e7c5d037270e9a1708150c619a1a | |
parent | 37e4e7f77d8f7b7e911bf611a0f8edbc3a850c7a (diff) | |
download | gcc-db4243bb681f7d4e82c15674eb3bfd9b82b0cf71.zip gcc-db4243bb681f7d4e82c15674eb3bfd9b82b0cf71.tar.gz gcc-db4243bb681f7d4e82c15674eb3bfd9b82b0cf71.tar.bz2 |
c++: constexpr empty aggr [PR105795]
In this testcase, leaving ctx->ctor pointing to the enclosing object meant
that evaluating the initializer for the subobject clobbered previous
initializers for the enclosing object. So do update ctx->ctor, just don't
add it to the enclosing object ctor.
PR c++/105795
gcc/cp/ChangeLog:
* constexpr.cc (cxx_eval_bare_aggregate): Always call
init_subob_ctx.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/constexpr-aggr-base1.C: New test.
-rw-r--r-- | gcc/cp/constexpr.cc | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/constexpr-aggr-base1.C | 27 |
2 files changed, 29 insertions, 5 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 4520847..021eaa3 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -4777,12 +4777,9 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, tree orig_value = value; /* Like in cxx_eval_store_expression, omit entries for empty fields. */ bool no_slot = TREE_CODE (type) == RECORD_TYPE && is_empty_field (index); - if (no_slot) - new_ctx = *ctx; - else - init_subob_ctx (ctx, new_ctx, index, value); + init_subob_ctx (ctx, new_ctx, index, value); int pos_hint = -1; - if (new_ctx.ctor != ctx->ctor) + if (new_ctx.ctor != ctx->ctor && !no_slot) { /* If we built a new CONSTRUCTOR, attach it now so that other initializers can refer to it. */ diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-aggr-base1.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-aggr-base1.C new file mode 100644 index 0000000..06acb4a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-aggr-base1.C @@ -0,0 +1,27 @@ +// PR c++/105795 +// { dg-do compile { target c++17 } } + +struct empty +{}; + +template <typename T> +struct tuple_holder +{ + [[no_unique_address]] T value; +}; + +struct tuple : tuple_holder<int>, tuple_holder<empty> +{}; + +constexpr auto make_tuple(int&& i, empty&& e) +{ + return tuple{i, e}; +} + +constexpr int foo() +{ + auto tuple = make_tuple(1, empty{}); + return static_cast<const tuple_holder<int>&>(tuple).value; +} + +static_assert (foo() == 1); |