diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6885,19 +6885,12 @@ 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. + // 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(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; + } + } } } } diff --git a/clang/test/SemaCXX/anonymous-struct.cpp b/clang/test/SemaCXX/anonymous-struct.cpp --- a/clang/test/SemaCXX/anonymous-struct.cpp +++ b/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;