c++: constexpr and empty fields [PR97566]
authorJason Merrill <jason@redhat.com>
Sun, 24 Jan 2021 05:55:49 +0000 (00:55 -0500)
committerJason Merrill <jason@redhat.com>
Tue, 26 Jan 2021 20:00:38 +0000 (15:00 -0500)
commita4dfd0f089af33f2af57bf422f9859405b9b4a16
treea464db65d5d3e2c6ce5e0afe1ef258cca6a7aa0e
parente80f1f6b7a339bce1db03567e497658ae32d135e
c++: constexpr and empty fields [PR97566]

In the discussion of PR98463, Jakub pointed out that in C++17 and up,
cxx_fold_indirect_ref_1 could use the field we build for an empty base.  I
tried implementing that, but it broke one of the tuple tests, so I did some
more digging.

To start with, I generalized the PR98463 patch to handle the case where we
do have a field, for an empty base or [[no_unique_address]] member.  This is
enough also for the no-field case because the member of the empty base must
itself be an empty field; if it weren't, the base would not be empty.

I looked for related PRs and found 97566, which was also fixed by the patch.
After some poking around to figure out why, I noticed that the testcase had
been breaking because E, though an empty class, has an ABI nvsize of one
byte, and we were giving the [[no_unique_address]] FIELD_DECL that
DECL_SIZE, whereas in build_base_field_1 empty base fields always get
DECL_SIZE zero, and various places were relying on that to recognize empty
fields.  So I adjusted both the size and the checking.  When I adjusted
check_bases I wondered if we were correctly handling bases with only empty
data members, but it appears we do.

I'm deferring the cxx_fold_indirect_ref_1 change until stage 1, as I don't
think it actually fixes anything.

gcc/cp/ChangeLog:

PR c++/97566
PR c++/98463
* class.c (layout_class_type): An empty field gets size 0.
(is_empty_field): New.
(check_bases): Check it.
* cp-tree.h (is_empty_field): Declare it.
* constexpr.c (cxx_eval_store_expression): Check it.
(cx_check_missing_mem_inits): Likewise.
* init.c (perform_member_init): Likewise.
* typeck2.c (process_init_constructor_record): Likewise.

gcc/testsuite/ChangeLog:

PR c++/97566
* g++.dg/cpp2a/no_unique_address10.C: New test.
* g++.dg/cpp2a/no_unique_address9.C: New test.
gcc/cp/class.c
gcc/cp/constexpr.c
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/cpp2a/no_unique_address10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/no_unique_address9.C [new file with mode: 0644]