Base fields for empty bases appear in initialization order, which may not be the same as layout order. If they also show up in a CONSTRUCTOR in that order, output_constructor_regular_field aborts because it understandably doesn't want to go backwards. I also considered making o_c_r_f more tolerant of the case where the out-of-order field has fieldsize 0, and so no actual data needs to be emitted, but we might as well avoid adding an element to the CONSTRUCTOR in the first place.
Tested x86_64-pc-linux-gnu, applying to trunk. * typeck2.c (process_init_constructor_record): Skip trivial initialization of an empty base. --- gcc/cp/typeck2.c | 7 +++++++ gcc/testsuite/g++.dg/cpp1z/aggr-base7.C | 8 ++++++++ gcc/cp/ChangeLog | 6 ++++++ 3 files changed, 21 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1z/aggr-base7.C diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index b265ea05741..456c4fcb748 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1627,6 +1627,13 @@ process_init_constructor_record (tree type, tree init, int nested, int flags, } } + if (DECL_SIZE (field) && integer_zerop (DECL_SIZE (field)) + && !TREE_SIDE_EFFECTS (next)) + /* Don't add trivial initialization of an empty base/field to the + constructor, as they might not be ordered the way the back-end + expects. */ + continue; + /* If this is a bitfield, now convert to the lowered type. */ if (type != TREE_TYPE (field)) next = cp_convert_and_check (TREE_TYPE (field), next, complain); diff --git a/gcc/testsuite/g++.dg/cpp1z/aggr-base7.C b/gcc/testsuite/g++.dg/cpp1z/aggr-base7.C new file mode 100644 index 00000000000..bc1793e79ca --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/aggr-base7.C @@ -0,0 +1,8 @@ +// PR c++/88690 +// { dg-do compile { target c++11 } } + +struct A { int a = 1; }; +struct B { int b = 0; }; +struct C { C() = default; C (const C&) = delete; }; +struct D : public B, public C {}; +struct E : A { D f; } g{}; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3009b58a3b4..89a1bcac80b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-02-20 Jason Merrill <ja...@redhat.com> + + PR c++/88690 - C++17 ICE with empty base in aggregate. + * typeck2.c (process_init_constructor_record): Skip trivial + initialization of an empty base. + 2019-02-21 Richard Biener <rguent...@suse.de> PR middle-end/89392 base-commit: f867b437c79cf560a55b778b947983bb08df158b -- 2.20.1