[PATCH] D80295: [Sema] Diagnose static data members in classes nested in unnamed classes

John Brawn via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed May 20 07:02:20 PDT 2020


john.brawn created this revision.
john.brawn added reviewers: rsmith, rjmccall.
Herald added a project: clang.

We currently diagnose static data members directly contained in unnamed classes, but we should also diagnose when they're in a class that is nested (directly or indirectly) in an unnamed class. Do this by iterating up the list of parent DeclContexts and checking if any is an unnamed class.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D80295

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaCXX/anonymous-struct.cpp


Index: clang/test/SemaCXX/anonymous-struct.cpp
===================================================================
--- clang/test/SemaCXX/anonymous-struct.cpp
+++ clang/test/SemaCXX/anonymous-struct.cpp
@@ -153,3 +153,21 @@
   const Empty E;
 } C;
 } // namespace ImplicitDecls
+
+struct {
+  static int x; // expected-error {{static data member 'x' not allowed in anonymous struct}}
+} static_member_1;
+
+struct {
+  struct A {
+    static int x; // expected-error {{static data member 'x' not allowed in anonymous struct}}
+  } x;
+} static_member_2;
+
+struct {
+  struct A {
+    struct B {
+      static int x; // expected-error {{static data member 'x' not allowed in anonymous struct}}
+    } x;
+  } x;
+} static_member_3;
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -6885,19 +6885,12 @@
 
     if (SC == SC_Static && CurContext->isRecord()) {
       if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) {
-        // C++ [class.static.data]p2:
-        //   A static data member shall not be a direct member of an unnamed
-        //   or local class
-        // FIXME: or of a (possibly indirectly) nested class thereof.
+        // C++ [class.static.data]p5: A local class shall not have static data
+        // members.
         if (RD->isLocalClass()) {
           Diag(D.getIdentifierLoc(),
                diag::err_static_data_member_not_allowed_in_local_class)
             << Name << RD->getDeclName() << RD->getTagKind();
-        } else if (!RD->getDeclName()) {
-          Diag(D.getIdentifierLoc(),
-               diag::err_static_data_member_not_allowed_in_anon_struct)
-            << Name << RD->getTagKind();
-          Invalid = true;
         } else if (RD->isUnion()) {
           // C++98 [class.union]p1: If a union contains a static data member,
           // the program is ill-formed. C++11 drops this restriction.
@@ -6905,6 +6898,21 @@
                getLangOpts().CPlusPlus11
                  ? diag::warn_cxx98_compat_static_data_member_in_union
                  : diag::ext_static_data_member_in_union) << Name;
+        } else {
+          // C++ [class.static.data]p4: Unnamed classes and classes contained
+          // directly or indirectly within unnamed classes shall not contain
+          // static data members.
+          for (DeclContext *ParentContext = DC;
+               RD = dyn_cast<CXXRecordDecl>(ParentContext);
+               ParentContext = ParentContext->getParent()) {
+            if (!RD->getDeclName()) {
+              Diag(D.getIdentifierLoc(),
+                   diag::err_static_data_member_not_allowed_in_anon_struct)
+                  << Name << RD->getTagKind();
+              Invalid = true;
+              break;
+            }
+          }
         }
       }
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D80295.265224.patch
Type: text/x-patch
Size: 2884 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200520/14922cd5/attachment.bin>


More information about the cfe-commits mailing list