Hi,

only when Jakub bumped some bugs in preparation for the release I noted that this one remained assigned to me for way too much time...

Roughly speaking, the problem is caused by the fact that when we have a GNU anonymous struct inside a union the fields are flattened out and appear to be just individual fields of the union. Thus we end up rejecting test1 below because multiple fields are initialized and we don't simply handle them later on as NSDMIs. A GNU anonymous struct is required for the issue to show up, thus the details of the way we want to handle such code are debatable, but we know that, eg, both EDG and clang accept test1 too (in relaxed GNU mode, at least), besides test2 and test3.

Given the underlying cause of the rejection I could easily imagine other less straightforward ways to match the cases at issues in check_field_decl (eg, along the lines DECL_CONTEXT (field) == t ??), but the below certainly passes testing on x86_64-linux.

Thanks,
Paolo.

////////////////////////////
/cp
2016-04-28  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/66644
        * class.c (check_field_decl): Do not reject multiple initialized
        fields in anonymous struct.

/testsuite
2016-04-28  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/66644
        * g++.dg/cpp0x/nsdmi-anon-struct1.C: New.
Index: cp/class.c
===================================================================
--- cp/class.c  (revision 235557)
+++ cp/class.c  (working copy)
@@ -3623,7 +3623,11 @@ check_field_decl (tree field,
     {
       /* `build_class_init_list' does not recognize
         non-FIELD_DECLs.  */
-      if (TREE_CODE (t) == UNION_TYPE && *any_default_members != 0)
+      if (TREE_CODE (t) == UNION_TYPE && *any_default_members != 0
+         /* As a GNU extension initializing in C++11 multiple fields
+            of an anonymous struct living inside a union is fine.  */
+         && !(TREE_CODE (DECL_CONTEXT (field)) == RECORD_TYPE
+              && ANON_AGGR_TYPE_P (DECL_CONTEXT (field))))
        error ("multiple fields in union %qT initialized", t);
       *any_default_members = 1;
     }
Index: testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C
===================================================================
--- testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C (revision 0)
+++ testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C (working copy)
@@ -0,0 +1,30 @@
+// PR c++/66644
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-pedantic" }
+
+struct test1  
+{
+  union
+  {
+    struct { char a=0, b=0; };
+    char buffer[16];
+  };
+};
+
+struct test2 
+{
+  union  
+  {
+    struct { char a=0, b; };
+    char buffer[16];
+  };
+};
+
+struct test3
+{
+  union
+  {
+    struct { char a, b; } test2{0,0};
+    char buffer[16];
+  };
+};

Reply via email to