[llvm-branch-commits] [cfe-branch] r197905 - ---Merging r196453

Bill Wendling isanbard at gmail.com
Mon Dec 23 02:02:34 PST 2013


Author: void
Date: Mon Dec 23 04:02:34 2013
New Revision: 197905

URL: http://llvm.org/viewvc/llvm-project?rev=197905&view=rev
Log:
---Merging r196453

    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/branches/release_34/lib/Parse/ParseDeclCXX.cpp
    cfe/branches/release_34/test/Parser/recovery.cpp

Modified: cfe/branches/release_34/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_34/lib/Parse/ParseDeclCXX.cpp?rev=197905&r1=197904&r2=197905&view=diff
==============================================================================
--- cfe/branches/release_34/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/branches/release_34/lib/Parse/ParseDeclCXX.cpp Mon Dec 23 04:02:34 2013
@@ -1427,7 +1427,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);
     return;
   }
 

Modified: cfe/branches/release_34/test/Parser/recovery.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_34/test/Parser/recovery.cpp?rev=197905&r1=197904&r2=197905&view=diff
==============================================================================
--- cfe/branches/release_34/test/Parser/recovery.cpp (original)
+++ cfe/branches/release_34/test/Parser/recovery.cpp Mon Dec 23 04:02:34 2013
@@ -119,3 +119,9 @@ void MissingSemiInFunction() {
   struct Inner4 {} // ok, no missing ';' here
   Inner5;
 }
+
+namespace PR17084 {
+enum class EnumID {};
+template <typename> struct TempID;
+template <> struct TempID<BadType> : BadType, EnumID::Garbage; // expected-error{{use of undeclared identifier 'BadType'}}
+}





More information about the llvm-branch-commits mailing list