forked from OSchip/llvm-project
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:
parent
7104af04ac
commit
66e300e6f9
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue