aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-02-21 13:16:15 -0500
committerJason Merrill <jason@gcc.gnu.org>2019-02-21 13:16:15 -0500
commit7b45322a5e5030d386a3ad3f747f5e390be4d3ff (patch)
tree6fcd5af2f5a869fe25729cfc965e662154b51ad0 /gcc
parentf64629aa9aefbdcf895b120f00caf5b18a17e3e4 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/typeck2.c7
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/aggr-base7.C8
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{};