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(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()) { + bool InAnonStruct = false; + for (DeclContext *Ctxt = DC; + const CXXRecordDecl *ParentDecl = dyn_cast(Ctxt); + Ctxt = Ctxt->getParent()) { + if (!ParentDecl->getDeclName()) { + InAnonStruct = true; + break; + } + } + if (InAnonStruct) { + // 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(); 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. 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;