From 7b45322a5e5030d386a3ad3f747f5e390be4d3ff Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 21 Feb 2019 13:16:15 -0500 Subject: [PATCH] PR c++/88690 - C++17 ICE with empty base in aggregate. 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. * typeck2.c (process_init_constructor_record): Skip trivial initialization of an empty base. From-SVN: r269073 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/typeck2.c | 7 +++++++ gcc/testsuite/g++.dg/cpp1z/aggr-base7.C | 8 ++++++++ 3 files changed, 21 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1z/aggr-base7.C 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 + + 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 PR middle-end/89392 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{}; -- 2.30.2