c++: constexpr std::construct_at on empty field [PR101663]
authorPatrick Palka <ppalka@redhat.com>
Thu, 12 Aug 2021 00:59:53 +0000 (20:59 -0400)
committerPatrick Palka <ppalka@redhat.com>
Thu, 12 Aug 2021 00:59:53 +0000 (20:59 -0400)
commit21fd62e5ca9967bba8f97fd6244a8c6a564c2146
tree80d182ca1748b98e17fe080b965816a359436027
parent58f87503427e27bb069bd1841100f3c53440d51a
c++: constexpr std::construct_at on empty field [PR101663]

Here during constexpr evaluation of

  std::construct_at(&a._M_value)

we find ourselves in cxx_eval_store_expression where the target object
is 'a._M_value' and the initializer is {}.  Since _M_value is an empty
[[no_unique_address]] member we don't create a sub-CONSTRUCTOR for it,
so we end up in the early exit code path for empty stores with mismatched
types and trip over the assert therein

  gcc_assert (is_empty_class (TREE_TYPE (init)) && !lval);

because lval is true.  The reason it's true is because the INIT_EXPR in
question is the LHS of a COMPOUND_EXPR, and evaluation of the LHS is
always performed with lval=true (to indicate there's no lvalue-to-rvalue
conversion).

This patch makes the code path in question handle the lval=true case
appropriately rather than asserting.  In passing, it also consolidates
the duplicate implementations of std::construct_at/destroy_at in some
of the C++20 constexpr tests into a common header file.

PR c++/101663

gcc/cp/ChangeLog:

* constexpr.c (cxx_eval_store_expression): Handle the lval=true
case in the early exit code path for empty stores with mismatched
types.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/construct_at.h: New convenience header file that
defines minimal implementations of std::construct_at/destroy_at,
split out from ...
* g++.dg/cpp2a/constexpr-new5.C: ... here.
* g++.dg/cpp2a/constexpr-new6.C: Use the header.
* g++.dg/cpp2a/constexpr-new14.C: Likewise.
* g++.dg/cpp2a/constexpr-new20.C: New test.
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp2a/constexpr-new14.C
gcc/testsuite/g++.dg/cpp2a/constexpr-new20.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/constexpr-new5.C
gcc/testsuite/g++.dg/cpp2a/constexpr-new6.C
gcc/testsuite/g++.dg/cpp2a/construct_at.h [new file with mode: 0644]