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

Matt Beaumont-Gay matthewbg at google.com
Thu Aug 1 13:40:37 PDT 2013


Thanks, this has been on my priority queue, but not near the top, for
a couple of weeks.

On Wed, Jul 31, 2013 at 9:22 PM, David Majnemer
<david.majnemer at gmail.com> wrote:
> 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.

Please avoid mixing unrelated formatting changes in with
semantics-changing commits.

>
> 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}}
> +};
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list