r187557 - Parse: Don't consider attributes of broken member declarators

David Majnemer david.majnemer at gmail.com
Wed Jul 31 21:22:55 PDT 2013


Author: majnemer
Date: Wed Jul 31 23:22:55 2013
New Revision: 187557

URL: http://llvm.org/viewvc/llvm-project?rev=187557&view=rev
Log:
Parse: Don't consider attributes of broken member declarators

ParseCXXClassMemberDeclaration was trying to use the result of
ActOnCXXMemberDeclarator to attach it to some late parsed attributes.

However when failures arise, we have no decl to attach to which
eventually leads us to a NULL pointer dereference.

While we are here, clean up the code a bit.

Fixes PR16765

Modified:
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/test/Parser/cxx-attributes.cpp

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=187557&r1=187556&r2=187557&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Jul 31 23:22:55 2013
@@ -2164,11 +2164,13 @@ void Parser::ParseCXXClassMemberDeclarat
         ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo,
                                 VS, DefinitionKind, Init);
 
-      for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
-        CommonLateParsedAttrs[i]->addDecl(FunDecl);
-      }
-      for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
-        LateParsedAttrs[i]->addDecl(FunDecl);
+      if (FunDecl) {
+        for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
+          CommonLateParsedAttrs[i]->addDecl(FunDecl);
+        }
+        for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
+          LateParsedAttrs[i]->addDecl(FunDecl);
+        }
       }
       LateParsedAttrs.clear();
 
@@ -2262,28 +2264,19 @@ void Parser::ParseCXXClassMemberDeclarat
                                                   TemplateParams,
                                                   BitfieldSize.release(),
                                                   VS, HasInClassInit);
-      if (AccessAttrs)
+      if (ThisDecl && AccessAttrs)
         Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs,
                                          false, true);
     }
-    
-    // Set the Decl for any late parsed attributes
-    for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
-      CommonLateParsedAttrs[i]->addDecl(ThisDecl);
-    }
-    for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
-      LateParsedAttrs[i]->addDecl(ThisDecl);
-    }
-    LateParsedAttrs.clear();
 
     // Handle the initializer.
     if (HasInClassInit != ICIS_NoInit &&
         DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
         DeclSpec::SCS_static) {
       // The initializer was deferred; parse it and cache the tokens.
-      Diag(Tok, getLangOpts().CPlusPlus11 ?
-           diag::warn_cxx98_compat_nonstatic_member_init :
-           diag::ext_nonstatic_member_init);
+      Diag(Tok, getLangOpts().CPlusPlus11
+                    ? diag::warn_cxx98_compat_nonstatic_member_init
+                    : diag::ext_nonstatic_member_init);
 
       if (DeclaratorInfo.isArrayOfUnknownBound()) {
         // C++11 [dcl.array]p3: An array bound may also be omitted when the
@@ -2293,37 +2286,45 @@ void Parser::ParseCXXClassMemberDeclarat
         // initializer in the grammar, so this is ill-formed.
         Diag(Tok, diag::err_incomplete_array_member_init);
         SkipUntil(tok::comma, true, true);
+
+        // Avoid later warnings about a class member of incomplete type.
         if (ThisDecl)
-          // Avoid later warnings about a class member of incomplete type.
           ThisDecl->setInvalidDecl();
       } else
         ParseCXXNonStaticMemberInitializer(ThisDecl);
     } else if (HasInitializer) {
       // Normal initializer.
       if (!Init.isUsable())
-        Init = ParseCXXMemberInitializer(ThisDecl,
-                 DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
-      
+        Init = ParseCXXMemberInitializer(
+            ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
+
       if (Init.isInvalid())
         SkipUntil(tok::comma, true, true);
       else if (ThisDecl)
         Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(),
                                      DS.containsPlaceholderType());
-    } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) {
+    } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static)
       // No initializer.
       Actions.ActOnUninitializedDecl(ThisDecl, DS.containsPlaceholderType());
-    }
-    
+
     if (ThisDecl) {
+      if (!ThisDecl->isInvalidDecl()) {
+        // Set the Decl for any late parsed attributes
+        for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)
+          CommonLateParsedAttrs[i]->addDecl(ThisDecl);
+
+        for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)
+          LateParsedAttrs[i]->addDecl(ThisDecl);
+      }
       Actions.FinalizeDeclaration(ThisDecl);
       DeclsInGroup.push_back(ThisDecl);
+
+      if (DeclaratorInfo.isFunctionDeclarator() &&
+          DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
+              DeclSpec::SCS_typedef)
+        HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
     }
-    
-    if (ThisDecl && DeclaratorInfo.isFunctionDeclarator() &&
-        DeclaratorInfo.getDeclSpec().getStorageClassSpec()
-          != DeclSpec::SCS_typedef) {
-      HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
-    }
+    LateParsedAttrs.clear();
 
     DeclaratorInfo.complete(ThisDecl);
 

Modified: cfe/trunk/test/Parser/cxx-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-attributes.cpp?rev=187557&r1=187556&r2=187557&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx-attributes.cpp Wed Jul 31 23:22:55 2013
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
 
 class c {
   virtual void f1(const char* a, ...)
@@ -8,3 +7,7 @@ class c {
     __attribute__ (( __format__(__printf__,2,3) )) {}
 };
 
+template <typename T> class X {
+  template <typename S> void X<S>::f() __attribute__((locks_excluded())); // expected-error{{nested name specifier 'X<S>::' for declaration does not refer into a class, class template or class template partial specialization}} \
+                                                                          // expected-warning{{attribute locks_excluded ignored, because it is not attached to a declaration}}
+};





More information about the cfe-commits mailing list