[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
Thu May 21 06:26:48 PDT 2020


john.brawn updated this revision to Diff 265486.
john.brawn marked an inline comment as done.
john.brawn added a comment.

Use the tag of the anonymous struct when emitting a diagnostic.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80295/new/

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;
+
+class {
+  struct A {
+    static int x; // expected-error {{static data member 'x' not allowed in anonymous class}}
+  } x;
+} static_member_2;
+
+union {
+  struct A {
+    struct B {
+      static int x; // expected-error {{static data member 'x' not allowed in anonymous union}}
+    } x;
+  } x;
+} static_member_3;
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -6885,19 +6885,29 @@
 
     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.
-        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()) {
+        const CXXRecordDecl *AnonStruct = nullptr;
+        for (DeclContext *Ctxt = DC;
+             const CXXRecordDecl *ParentDecl = dyn_cast<CXXRecordDecl>(Ctxt);
+             Ctxt = Ctxt->getParent()) {
+          if (!ParentDecl->getDeclName()) {
+            AnonStruct = ParentDecl;
+            break;
+          }
+        }
+        if (AnonStruct) {
+          // C++ [class.static.data]p4: Unnamed classes and classes contained
+          // directly or indirectly within unnamed classes shall not contain
+          // static data members.
           Diag(D.getIdentifierLoc(),
                diag::err_static_data_member_not_allowed_in_anon_struct)
-            << Name << RD->getTagKind();
+            << Name << AnonStruct->getTagKind();
           Invalid = true;
+        } else if (RD->isLocalClass()) {
+          // C++ [class.static.data]p5: A local class shall not have static data
+          // members.
+          Diag(D.getIdentifierLoc(),
+               diag::err_static_data_member_not_allowed_in_local_class)
+            << Name << RD->getDeclName() << RD->getTagKind();
         } 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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D80295.265486.patch
Type: text/x-patch
Size: 2806 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200521/dccbcf83/attachment-0001.bin>


More information about the cfe-commits mailing list