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