]> granicus.if.org Git - clang/commitdiff
Thread safety analysis: Fixed ICE caused by double delete when late parsed
authorDeLesley Hutchins <delesley@google.com>
Fri, 2 Nov 2012 21:44:32 +0000 (21:44 +0000)
committerDeLesley Hutchins <delesley@google.com>
Fri, 2 Nov 2012 21:44:32 +0000 (21:44 +0000)
attributes are attached to function declarations nested inside a class method.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167321 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Parser.h
lib/Parse/ParseDecl.cpp
lib/Parse/ParseTemplate.cpp
test/SemaCXX/warn-thread-safety-parsing.cpp

index e16aeadb08657f184223bc5f3ad9b1b167c0305f..ef69611a4c1df2639284a11e5f24667aed73b4c7 100644 (file)
@@ -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
index 7b4fbfc2871715178ca0a416742727100ca48995..d45f038f31c977f257311ea0ff62a8a1ccf56551 100644 (file)
@@ -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);
 
index 11be3600bdc4e1cd3bef04b012520a5f8c50cf04..2e0411e8a81c163f5949776d1bafca201ac0663f 100644 (file)
@@ -246,7 +246,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
     return 0;
   }
 
-  LateParsedAttrList LateParsedAttrs;
+  LateParsedAttrList LateParsedAttrs(true);
   if (DeclaratorInfo.isFunctionDeclarator())
     MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
 
index 92c4b107a13f6aa54a4080a19e8cb563a5491abc..df9415cf8601aa3057dd8f98603e8775c803fc96 100644 (file)
@@ -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