Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -6885,18 +6885,34 @@ 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()) { + // Walk up the enclosing DeclContexts to check for any that are + // incompatible with static data members. + const DeclContext *FunctionOrMethod = nullptr; + const CXXRecordDecl *AnonStruct = nullptr; + for (DeclContext *Ctxt = DC; Ctxt; Ctxt = Ctxt->getParent()) { + if (Ctxt->isFunctionOrMethod()) { + FunctionOrMethod = Ctxt; + break; + } + const CXXRecordDecl *ParentDecl = dyn_cast(Ctxt); + if (ParentDecl && !ParentDecl->getDeclName()) { + AnonStruct = ParentDecl; + break; + } + } + if (FunctionOrMethod) { + // 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->getDeclName()) { + } else 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->isUnion()) { // C++98 [class.union]p1: If a union contains a static data member, Index: clang/test/OpenMP/for_loop_messages.cpp =================================================================== --- clang/test/OpenMP/for_loop_messages.cpp +++ clang/test/OpenMP/for_loop_messages.cpp @@ -831,3 +831,13 @@ for (int i = 0; i < 16; ++i) ; } + +void test_static_data_member() { +#pragma omp parallel +#pragma omp for + for (int i = 0; i < 16; ++i) { + class X { + static int x; // expected-error {{static data member 'x' not allowed in local class 'X'}} + }; + } +} 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/test/SemaCXX/blocks.cpp =================================================================== --- clang/test/SemaCXX/blocks.cpp +++ clang/test/SemaCXX/blocks.cpp @@ -153,3 +153,16 @@ auto some_block = ^{ (void)s; }; } } + +void static_data_member() { + auto block = ^{ + class X { + static int x; // expected-error {{static data member 'x' not allowed in local class 'X'}} + }; + class Y { + struct Z { + static int z; // expected-error {{static data member 'z' not allowed in local struct 'Z'}} + }; + }; + }; +}