diff options
author | Jason Merrill <jason@redhat.com> | 2019-02-21 13:16:15 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2019-02-21 13:16:15 -0500 |
commit | 7b45322a5e5030d386a3ad3f747f5e390be4d3ff (patch) | |
tree | 6fcd5af2f5a869fe25729cfc965e662154b51ad0 /gcc | |
parent | f64629aa9aefbdcf895b120f00caf5b18a17e3e4 (diff) | |
download | gcc-7b45322a5e5030d386a3ad3f747f5e390be4d3ff.zip gcc-7b45322a5e5030d386a3ad3f747f5e390be4d3ff.tar.gz gcc-7b45322a5e5030d386a3ad3f747f5e390be4d3ff.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/aggr-base7.C | 8 |
3 files changed, 21 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3009b58..89a1bca 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-02-20 Jason Merrill <jason@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 <rguenther@suse.de> PR middle-end/89392 diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index b265ea0..456c4fc 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 0000000..bc1793e --- /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{}; |