Thread safety analysis: Fixed ICE caused by double delete when late parsed

attributes are attached to function declarations nested inside a class method.

llvm-svn: 167321
This commit is contained in:
DeLesley Hutchins 2012-11-02 21:44:32 +00:00
parent 7104af04ac
commit 66e300e6f9
4 changed files with 37 additions and 5 deletions

View File

@ -848,9 +848,16 @@ private:
void addDecl(Decl *D) { Decls.push_back(D); } void addDecl(Decl *D) { Decls.push_back(D); }
}; };
/// A list of late parsed attributes. Used by ParseGNUAttributes. // A list of late-parsed attributes. Used by ParseGNUAttributes.
typedef llvm::SmallVector<LateParsedAttribute*, 2> LateParsedAttrList; 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 /// Contains the lexed tokens of a member function definition
/// which needs to be parsed at the end of the class declaration /// which needs to be parsed at the end of the class declaration

View File

@ -143,7 +143,7 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
// Attributes in a class are parsed at the end of the class, along // Attributes in a class are parsed at the end of the class, along
// with other late-parsed declarations. // with other late-parsed declarations.
if (!ClassStack.empty()) if (!ClassStack.empty() && !LateAttrs->parseSoon())
getCurrentClass().LateParsedDeclarations.push_back(LA); getCurrentClass().LateParsedDeclarations.push_back(LA);
// consume everything up to and including the matching right parens // 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. /// \brief Parse all attributes in LAs, and attach them to Decl D.
void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
bool EnterScope, bool OnDefinition) { 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) { for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
if (D) if (D)
LAs[i]->addDecl(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 // Save late-parsed attributes for now; they need to be parsed in the
// appropriate function scope after the function Decl has been constructed. // 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()) if (D.isFunctionDeclarator())
MaybeParseGNUAttributes(D, &LateParsedAttrs); MaybeParseGNUAttributes(D, &LateParsedAttrs);

View File

@ -246,7 +246,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
return 0; return 0;
} }
LateParsedAttrList LateParsedAttrs; LateParsedAttrList LateParsedAttrs(true);
if (DeclaratorInfo.isFunctionDeclarator()) if (DeclaratorInfo.isFunctionDeclarator())
MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);

View File

@ -1464,4 +1464,26 @@ class Foo {
} // end namespace StaticScopeTest } // 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