diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 0da509280068a..99d698f57982f 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -449,6 +449,8 @@ def err_typename_invalid_constexpr : Error< "to be specified">; def err_typename_identifiers_only : Error< "typename is allowed for identifiers only">; +def err_storage_class_before_class_decl : Error< + "'%0' is not allowed before a class declaration">; def err_friend_invalid_in_context : Error< "'friend' used outside of class">; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 04c2f1d380bc4..2145f78f4b274 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1254,6 +1254,18 @@ Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition( Actions.getASTContext().getSourceManager()); }); + if (DS->getStorageClassSpec() != DeclSpec::SCS_unspecified) { + // Check if the next token starts a class/struct/union/enum declaration + if (Tok.isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union, tok::kw_enum)) { + // Emit an error: storage class specifiers are not allowed before class declarations + Diag(DS->getStorageClassSpecLoc(), diag::err_storage_class_before_class_decl) + << DeclSpec::getSpecifierName(DS->getStorageClassSpec()); + + // Optionally, consume the storage class specifier to continue parsing + DS->ClearStorageClassSpecs(); + } + } + if (DS) { return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, *DS, AS); } else { diff --git a/clang/test/SemaCXX/invalid-storage-class.cpp b/clang/test/SemaCXX/invalid-storage-class.cpp new file mode 100644 index 0000000000000..ce0dee3711ac0 --- /dev/null +++ b/clang/test/SemaCXX/invalid-storage-class.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +auto class X1 {}; // expected-error {{'auto' is not allowed before a class declaration}} + +static struct X2 {}; // expected-error {{'static' is not allowed before a class declaration}} + +register union X3 {}; // expected-error {{'register' is not allowed before a class declaration}} \ No newline at end of file