<div dir="ltr">On Thu, Aug 1, 2013 at 1:40 PM, Matt Beaumont-Gay <span dir="ltr"><<a href="mailto:matthewbg@google.com" target="_blank">matthewbg@google.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks, this has been on my priority queue, but not near the top, for<br>
a couple of weeks.<br>
<div class="im"><br>
On Wed, Jul 31, 2013 at 9:22 PM, David Majnemer<br>
<<a href="mailto:david.majnemer@gmail.com">david.majnemer@gmail.com</a>> wrote:<br>
> Author: majnemer<br>
> Date: Wed Jul 31 23:22:55 2013<br>
> New Revision: 187557<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=187557&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=187557&view=rev</a><br>
> Log:<br>
> Parse: Don't consider attributes of broken member declarators<br>
><br>
> ParseCXXClassMemberDeclaration was trying to use the result of<br>
> ActOnCXXMemberDeclarator to attach it to some late parsed attributes.<br>
><br>
> However when failures arise, we have no decl to attach to which<br>
> eventually leads us to a NULL pointer dereference.<br>
><br>
> While we are here, clean up the code a bit.<br>
<br>
</div>Please avoid mixing unrelated formatting changes in with<br>
semantics-changing commits.<br></blockquote><div><br></div><div>Normally I would, it was done on special request for Richard :)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="HOEnZb"><div class="h5"><br>
><br>
> Fixes PR16765<br>
><br>
> Modified:<br>
>     cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
>     cfe/trunk/test/Parser/cxx-attributes.cpp<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=187557&r1=187556&r2=187557&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=187557&r1=187556&r2=187557&view=diff</a><br>

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

> ==============================================================================<br>
> --- cfe/trunk/test/Parser/cxx-attributes.cpp (original)<br>
> +++ cfe/trunk/test/Parser/cxx-attributes.cpp Wed Jul 31 23:22:55 2013<br>
> @@ -1,5 +1,4 @@<br>
>  // RUN: %clang_cc1 -fsyntax-only -verify %s<br>
> -// expected-no-diagnostics<br>
><br>
>  class c {<br>
>    virtual void f1(const char* a, ...)<br>
> @@ -8,3 +7,7 @@ class c {<br>
>      __attribute__ (( __format__(__printf__,2,3) )) {}<br>
>  };<br>
><br>
> +template <typename T> class X {<br>
> +  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}} \<br>

> +                                                                          // expected-warning{{attribute locks_excluded ignored, because it is not attached to a declaration}}<br>
> +};<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div></div>