diff mbox series

PR c++/88690 - C++17 ICE with empty base in aggregate.

Message ID 20190221181541.16426-1-jason@redhat.com
State New
Headers show
Series PR c++/88690 - C++17 ICE with empty base in aggregate. | expand

Commit Message

Jason Merrill Feb. 21, 2019, 6:15 p.m. UTC
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


base-commit: f867b437c79cf560a55b778b947983bb08df158b
diff mbox series

Patch

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  <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