output_constructor_field doesn't like to see two fields at offset zero
with non-zero size.  Fixed by giving the empty base field size zero.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit c5e03948968ee268d4bf9f1f7ceb8613a5b0f2a4
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Feb 16 11:23:57 2018 -0500

            PR c++/82764 - C++17 ICE with empty base
    
            * class.c (build_base_field_1): Set DECL_SIZE to zero for empty
            base.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index e48a04ade7d..296305ea644 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4216,8 +4216,14 @@ build_base_field_1 (tree t, tree basetype, tree 
*&next_field)
   DECL_ARTIFICIAL (decl) = 1;
   DECL_IGNORED_P (decl) = 1;
   DECL_FIELD_CONTEXT (decl) = t;
-  DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
-  DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
+  if (is_empty_class (basetype))
+    /* CLASSTYPE_SIZE is one byte, but the field needs to have size zero.  */
+    DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = size_zero_node;
+  else
+    {
+      DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
+      DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
+    }
   SET_DECL_ALIGN (decl, CLASSTYPE_ALIGN (basetype));
   DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
   SET_DECL_MODE (decl, TYPE_MODE (basetype));
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-empty1.C 
b/gcc/testsuite/g++.dg/cpp0x/nsdmi-empty1.C
new file mode 100644
index 00000000000..66d94e53824
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-empty1.C
@@ -0,0 +1,18 @@
+// PR c++/82764
+// { dg-do compile { target c++11 } }
+
+struct Empty {};
+struct Empty2 : Empty {};
+
+struct A : Empty2
+{
+  int x {1};
+  int y {2};
+};
+
+struct B
+{
+  A a {};
+};
+
+B b;

Reply via email to