r196453 - Parse: Recover better from bad definitions with base specifiers

Nico Weber thakis at chromium.org
Sat Feb 14 23:29:54 PST 2015


On Wed, Dec 4, 2013 at 5:36 PM, David Majnemer <david.majnemer at gmail.com>
wrote:

> Author: majnemer
> Date: Wed Dec  4 19:36:53 2013
> New Revision: 196453
>
> URL: http://llvm.org/viewvc/llvm-project?rev=196453&view=rev
> Log:
> Parse: Recover better from bad definitions with base specifiers
>
> We would skip until the next comma, hoping good things whould lie there,
> however this would fail when we have such things as this:
>
> struct A {};
> template <typename>
> struct D;
> template <>
> struct D<C> : B, A::D;
>
> Once this happens, we would believe that D with a nested namespace
> specifier of A was a variable that was being declared. We would go on
> to complain that there was an extraneous 'template <>' on their variable
> declaration.
>
> Crashes would happen when 'A' gets defined as 'enum class A {}' as
> various asserts would fire.
>
> Instead, we should skip up until the semicolon if we see that we are in
> the middle of a definition and the current token is a ':'
>
> This fixes PR17084.
>
> Modified:
>     cfe/trunk/lib/Parse/ParseDeclCXX.cpp
>     cfe/trunk/test/Parser/recovery.cpp
>
> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=196453&r1=196452&r2=196453&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Dec  4 19:36:53 2013
> @@ -1429,7 +1429,13 @@ void Parser::ParseClassSpecifier(tok::To
>          << DeclSpec::getSpecifierName(TagType);
>      }
>
> -    SkipUntil(tok::comma, StopAtSemi);
> +    // If we are parsing a definition and stop at a base-clause, continue
> on
> +    // until the semicolon.  Continuing from the comma will just trick us
> into
> +    // thinking we are seeing a variable declaration.
> +    if (TUK == Sema::TUK_Definition && Tok.is(tok::colon))
> +      SkipUntil(tok::semi, StopBeforeMatch);
> +    else
> +      SkipUntil(tok::comma, StopAtSemi);
>

Does it ever make sense to only skip to a comma? Where is this useful? (I
realize the tok::comma skipping predates your patch, but since you touched
this a short 1.2 years ago, maybe you know :-) Looking at the commit that
originally added it wasn't enlightening. I looked at this because of
r229288.)


>      return;
>    }
>
>
> Modified: cfe/trunk/test/Parser/recovery.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/recovery.cpp?rev=196453&r1=196452&r2=196453&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/Parser/recovery.cpp (original)
> +++ cfe/trunk/test/Parser/recovery.cpp Wed Dec  4 19:36:53 2013
> @@ -129,3 +129,9 @@ NS::Foo<int> missingSemiBeforeFunctionRe
>  using NS::Foo;
>  struct MissingSemiThenTemplate2 {} // expected-error {{expected ';' after
> struct}}
>  Foo<int> missingSemiBeforeFunctionReturningTemplateId2();
> +
> +namespace PR17084 {
> +enum class EnumID {};
> +template <typename> struct TempID;
> +template <> struct TempID<BadType> : BadType, EnumID::Garbage; //
> expected-error{{use of undeclared identifier 'BadType'}}
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150214/cef61a87/attachment.html>


More information about the cfe-commits mailing list