[PATCH] Parse: Recover better from bad definitions with base specifiers
David Majnemer
david.majnemer at gmail.com
Sat Sep 14 00:53:04 PDT 2013
Hi rsmith, doug.gregor,
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.
http://llvm-reviews.chandlerc.com/D1687
Files:
lib/Parse/ParseDeclCXX.cpp
test/Parser/recovery.cpp
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp
+++ lib/Parse/ParseDeclCXX.cpp
@@ -1419,8 +1419,14 @@
Diag(StartLoc, diag::err_anon_type_definition)
<< DeclSpec::getSpecifierName(TagType);
}
-
- SkipUntil(tok::comma, true);
+ // 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 && getLangOpts().CPlusPlus &&
+ Tok.is(tok::colon))
+ SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
+ else
+ SkipUntil(tok::comma, /*StopAtSemi=*/true);
return;
}
Index: test/Parser/recovery.cpp
===================================================================
--- test/Parser/recovery.cpp
+++ test/Parser/recovery.cpp
@@ -50,3 +50,9 @@
struct Redefined { // expected-error {{redefinition}}
Redefined() {}
};
+
+namespace PR17084 {
+enum class EnumID {};
+template <typename> struct TempID;
+template <> struct TempID<BadType> : BadType, EnumID::Garbage; // expected-error{{use of undeclared identifier 'BadType'}}
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1687.1.patch
Type: text/x-patch
Size: 1257 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130914/2071fc9b/attachment.bin>
More information about the cfe-commits
mailing list