PR c++/88690 - C++17 ICE with empty base in aggregate.
authorJason Merrill <jason@redhat.com>
Thu, 21 Feb 2019 18:16:15 +0000 (13:16 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 21 Feb 2019 18:16:15 +0000 (13:16 -0500)
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
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/cpp1z/aggr-base7.C [new file with mode: 0644]

index 3009b58a3b468b3b000d6fefd81a79e2e3a69191..89a1bcac80b3d1d36e191c07ce5ae871d142b8db 100644 (file)
@@ -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
index b265ea057416241360066c53d288dab6bea233bc..456c4fcb74847bfd43f6bf8fb5a546213b7eb6b9 100644 (file)
@@ -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 (file)
index 0000000..bc1793e
--- /dev/null
@@ -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{};