decl2.c (finish_static_data_member_decl): Diagnose static data member in unnamed...
authorJason Merrill <jason@redhat.com>
Tue, 25 Feb 2014 21:18:19 +0000 (16:18 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 25 Feb 2014 21:18:19 +0000 (16:18 -0500)
* decl2.c (finish_static_data_member_decl): Diagnose static data
member in unnamed class.

From-SVN: r208156

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl2.c
gcc/testsuite/g++.dg/ext/anon-struct5.C
gcc/testsuite/g++.dg/ext/anon-struct6.C
gcc/testsuite/g++.dg/parse/unnamed1.C [new file with mode: 0644]

index 393b213..9e3a63e 100644 (file)
@@ -1,5 +1,9 @@
 2014-02-25  Jason Merrill  <jason@redhat.com>
 
+       * decl2.c (finish_static_data_member_decl): Diagnose static data
+       member in unnamed class.
+       * class.c (finish_struct_anon_r): Avoid redundant diagnostic.
+
        PR lto/53808
        * class.c (clone_function_decl): Call note_vague_linkage_fn for
        defaulted virtual dtor.
index e861e4d..f61dc9d 100644 (file)
@@ -2851,7 +2851,9 @@ finish_struct_anon_r (tree field, bool complain)
 
       if (TREE_CODE (elt) != FIELD_DECL)
        {
-         if (complain)
+         /* We already complained about static data members in
+            finish_static_data_member_decl.  */
+         if (complain && TREE_CODE (elt) != VAR_DECL)
            {
              if (is_union)
                permerror (input_location,
index 35707a0..f512541 100644 (file)
@@ -802,6 +802,17 @@ finish_static_data_member_decl (tree decl,
       && !DECL_TEMPLATE_INSTANTIATION (decl))
     permerror (input_location, "local class %q#T shall not have static data member %q#D",
               current_class_type, decl);
+  else
+    for (tree t = current_class_type; TYPE_P (t);
+        t = CP_TYPE_CONTEXT (t))
+      if (TYPE_ANONYMOUS_P (t))
+       {
+         if (permerror (DECL_SOURCE_LOCATION (decl),
+                        "static data member %qD in unnamed class", decl))
+           inform (DECL_SOURCE_LOCATION (TYPE_NAME (t)),
+                   "unnamed class defined here");
+         break;
+       }
 
   DECL_IN_AGGR_P (decl) = 1;
 
index 8b697cc..ec02225 100644 (file)
@@ -2,12 +2,12 @@
 
 struct A
 {
-  struct { static int i; }; // { dg-error "prohibits anonymous structs|an anonymous struct" }
+  struct { static int i; }; // { dg-error "prohibits anonymous structs|an anonymous struct|unnamed class" }
   void foo() { i; }
 };
 
 struct B
 {
-  union { static int i; }; // { dg-error "an anonymous union|member of a union" }
+  union { static int i; }; // { dg-error "an anonymous union|member of a union|unnamed class" }
   void foo() { i; }
 };
index 11a7bbd..66d4b32 100644 (file)
@@ -4,7 +4,7 @@ struct A
 {
   struct
   {  // { dg-error "anonymous struct cannot have function members" }
-    struct { static int i; }; // { dg-error "prohibits anonymous structs|non-static data members" } 
+    struct { static int i; }; // { dg-error "prohibits anonymous structs|non-static data members|unnamed class" }
     void foo() { i; }
   }; // { dg-error "prohibits anonymous structs" }
 };
diff --git a/gcc/testsuite/g++.dg/parse/unnamed1.C b/gcc/testsuite/g++.dg/parse/unnamed1.C
new file mode 100644 (file)
index 0000000..f5972f1
--- /dev/null
@@ -0,0 +1,6 @@
+// 9.4.2/4: Unnamed classes and classes contained directly or indirectly
+// within unnamed classes shall not contain static data members.
+
+typedef struct {               // { dg-message "unnamed" }
+  static int i;                        // { dg-error "static data member" }
+} A;