re PR c++/66644 (Rejects C++11 in-class anonymous union members initialization)
authorPaolo Carlini <paolo.carlini@oracle.com>
Sat, 30 Apr 2016 00:00:51 +0000 (00:00 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sat, 30 Apr 2016 00:00:51 +0000 (00:00 +0000)
/cp
2016-04-29  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/66644
* class.c (check_field_decl): Remove final int* parameter, change
the return type to bool; fix logic in order not to reject multiple
initialized fields in anonymous struct.
(check_field_decls): Adjust call.

/testsuite
2016-04-29  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/66644
* g++.dg/cpp0x/nsdmi-anon-struct1.C: New.

From-SVN: r235662

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C [new file with mode: 0644]

index bb2b7cf5d12dcdeab423d958798cc628c2e179ba..25af3f2603e3e2e66ed06df9a5b01033a04efcf1 100644 (file)
@@ -1,3 +1,11 @@
+2016-04-29  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/66644
+       * class.c (check_field_decl): Remove final int* parameter, change
+       the return type to bool; fix logic in order not to reject multiple
+       initialized fields in anonymous struct.
+       (check_field_decls): Adjust call.
+
 2016-04-29  Cesar Philippidis  <cesar@codesourcery.com>
 
        PR middle-end/70626
index 2705e189afa17997ad8d6691c87dde3b2e1eb4d2..31fa4b03136a0b4d187bfbc6f5a93bd1cc1b4fbd 100644 (file)
@@ -139,7 +139,7 @@ static int count_fields (tree);
 static int add_fields_to_record_type (tree, struct sorted_fields_type*, int);
 static void insert_into_classtype_sorted_fields (tree, tree, int);
 static bool check_bitfield_decl (tree);
-static void check_field_decl (tree, tree, int *, int *, int *);
+static bool check_field_decl (tree, tree, int *, int *);
 static void check_field_decls (tree, tree *, int *, int *);
 static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
 static void build_base_fields (record_layout_info, splay_tree, tree *);
@@ -3541,14 +3541,14 @@ check_bitfield_decl (tree field)
    enclosing type T.  Issue any appropriate messages and set appropriate
    flags.  */
 
-static void
+static bool
 check_field_decl (tree field,
                  tree t,
                  int* cant_have_const_ctor,
-                 int* no_const_asn_ref,
-                 int* any_default_members)
+                 int* no_const_asn_ref)
 {
   tree type = strip_array_types (TREE_TYPE (field));
+  bool any_default_members = false;
 
   /* In C++98 an anonymous union cannot contain any fields which would change
      the settings of CANT_HAVE_CONST_CTOR and friends.  */
@@ -3558,12 +3558,12 @@ check_field_decl (tree field,
      structs.  So, we recurse through their fields here.  */
   else if (ANON_AGGR_TYPE_P (type))
     {
-      tree fields;
-
-      for (fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN (fields))
+      for (tree fields = TYPE_FIELDS (type); fields;
+          fields = DECL_CHAIN (fields))
        if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field))
-         check_field_decl (fields, t, cant_have_const_ctor,
-                           no_const_asn_ref, any_default_members);
+         any_default_members |= check_field_decl (fields, t,
+                                                  cant_have_const_ctor,
+                                                  no_const_asn_ref);
     }
   /* Check members with class type for constructors, destructors,
      etc.  */
@@ -3620,13 +3620,11 @@ check_field_decl (tree field,
   check_abi_tags (t, field);
 
   if (DECL_INITIAL (field) != NULL_TREE)
-    {
-      /* `build_class_init_list' does not recognize
-        non-FIELD_DECLs.  */
-      if (TREE_CODE (t) == UNION_TYPE && *any_default_members != 0)
-       error ("multiple fields in union %qT initialized", t);
-      *any_default_members = 1;
-    }
+    /* `build_class_init_list' does not recognize
+       non-FIELD_DECLs.  */
+    any_default_members = true;
+
+  return any_default_members;
 }
 
 /* Check the data members (both static and non-static), class-scoped
@@ -3662,7 +3660,7 @@ check_field_decls (tree t, tree *access_decls,
   tree *field;
   tree *next;
   bool has_pointers;
-  int any_default_members;
+  bool any_default_members;
   int cant_pack = 0;
   int field_access = -1;
 
@@ -3672,7 +3670,7 @@ check_field_decls (tree t, tree *access_decls,
   has_pointers = false;
   /* Assume none of the members of this class have default
      initializations.  */
-  any_default_members = 0;
+  any_default_members = false;
 
   for (field = &TYPE_FIELDS (t); *field; field = next)
     {
@@ -3867,11 +3865,16 @@ check_field_decls (tree t, tree *access_decls,
 
       /* We set DECL_C_BIT_FIELD in grokbitfield.
         If the type and width are valid, we'll also set DECL_BIT_FIELD.  */
-      if (! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x))
-       check_field_decl (x, t,
-                         cant_have_const_ctor_p,
-                         no_const_asn_ref_p,
-                         &any_default_members);
+      if ((! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x))
+         && check_field_decl (x, t,
+                              cant_have_const_ctor_p,
+                              no_const_asn_ref_p))
+       {
+         if (any_default_members
+             && TREE_CODE (t) == UNION_TYPE)
+           error ("multiple fields in union %qT initialized", t);
+         any_default_members = true;
+       }
 
       /* Now that we've removed bit-field widths from DECL_INITIAL,
         anything left in DECL_INITIAL is an NSDMI that makes the class
index cf91897dc02e2b82a9832c425cf8c47bcf51e97a..b1d63d824f7000bb731323c7a37c3d51c91928b5 100644 (file)
@@ -1,3 +1,8 @@
+2016-04-29  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/66644
+       * g++.dg/cpp0x/nsdmi-anon-struct1.C: New.
+
 2016-04-29  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        * gcc.target/powerpc/vsx-elemrev-1.c: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C
new file mode 100644 (file)
index 0000000..35c342a
--- /dev/null
@@ -0,0 +1,48 @@
+// 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];
+  };
+};
+
+struct test4
+{
+  union  
+  {   // { dg-error "multiple fields" }
+    struct { char a=0, b=0; };
+    struct { char c=0, d; };
+  };
+};
+
+struct test5
+{
+  union
+  {
+    union { char a=0, b=0; };  // { dg-error "multiple fields" }
+    char buffer[16];
+  };
+};