diff options
-rw-r--r-- | include/clang/Parse/Parser.h | 11 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 7 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/warn-thread-safety-parsing.cpp | 22 |
4 files changed, 37 insertions, 5 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index e16aeadb08..ef69611a4c 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -848,9 +848,16 @@ private: void addDecl(Decl *D) { Decls.push_back(D); } }; - /// A list of late parsed attributes. Used by ParseGNUAttributes. - typedef llvm::SmallVector<LateParsedAttribute*, 2> LateParsedAttrList; + // A list of late-parsed attributes. Used by ParseGNUAttributes. + class LateParsedAttrList: public llvm::SmallVector<LateParsedAttribute*, 2> { + public: + LateParsedAttrList(bool PSoon = false) : ParseSoon(PSoon) { } + + bool parseSoon() { return ParseSoon; } + private: + bool ParseSoon; // Are we planning to parse these shortly after creation? + }; /// Contains the lexed tokens of a member function definition /// which needs to be parsed at the end of the class declaration diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 7b4fbfc287..d45f038f31 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -143,7 +143,7 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs, // Attributes in a class are parsed at the end of the class, along // with other late-parsed declarations. - if (!ClassStack.empty()) + if (!ClassStack.empty() && !LateAttrs->parseSoon()) getCurrentClass().LateParsedDeclarations.push_back(LA); // consume everything up to and including the matching right parens @@ -871,6 +871,8 @@ void Parser::ParseLexedAttributes(ParsingClass &Class) { /// \brief Parse all attributes in LAs, and attach them to Decl D. void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, bool EnterScope, bool OnDefinition) { + assert(LAs.parseSoon() && + "Attribute list should be marked for immediate parsing."); for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { if (D) LAs[i]->addDecl(D); @@ -1413,7 +1415,8 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, // Save late-parsed attributes for now; they need to be parsed in the // appropriate function scope after the function Decl has been constructed. - LateParsedAttrList LateParsedAttrs; + // These will be parsed in ParseFunctionDefinition or ParseLexedAttrList. + LateParsedAttrList LateParsedAttrs(true); if (D.isFunctionDeclarator()) MaybeParseGNUAttributes(D, &LateParsedAttrs); diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 11be3600bd..2e0411e8a8 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -246,7 +246,7 @@ Parser::ParseSingleDeclarationAfterTemplate( return 0; } - LateParsedAttrList LateParsedAttrs; + LateParsedAttrList LateParsedAttrs(true); if (DeclaratorInfo.isFunctionDeclarator()) MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp index 92c4b107a1..df9415cf86 100644 --- a/test/SemaCXX/warn-thread-safety-parsing.cpp +++ b/test/SemaCXX/warn-thread-safety-parsing.cpp @@ -1464,4 +1464,26 @@ class Foo { } // end namespace StaticScopeTest +namespace FunctionAttributesInsideClass_ICE_Test { + +class Foo { +public: + /* Originally found when parsing foo() as an ordinary method after the + * the following: + + template <class T> + void syntaxErrorMethod(int i) { + if (i) { + foo( + } + } + */ + + void method() { + void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \ + // expected-error {{use of undeclared identifier 'mu'}} + } +}; + +} // end namespace FunctionAttributesInsideClass_ICE_Test |