diff options
author | John McCall <rjmccall@apple.com> | 2010-07-30 06:26:29 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-07-30 06:26:29 +0000 |
commit | 207014eb2b372aa33721e86d90a8a586ba8dc8ae (patch) | |
tree | 4b927c519af3af593ad65ec58ba61855c618d75e | |
parent | 27940d2fb346325d6001a7661e4ada099cd8e59c (diff) |
Improve error recovery when presented with an ill-formed template-id
(e.g. due to a broken template argument) following template parameters.
Fixes rdar://problem/8254267
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109853 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 14 | ||||
-rw-r--r-- | test/SemaTemplate/class-template-id.cpp | 4 | ||||
-rw-r--r-- | test/SemaTemplate/deduction-crash.cpp | 2 |
3 files changed, 14 insertions, 6 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index e6db331200..7ed07a277c 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -680,7 +680,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // "FOO : BAR" is not a potential typo for "FOO::BAR". ColonProtectionRAIIObject X(*this); - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true); + if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true)) + DS.SetTypeSpecError(); if (SS.isSet()) if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) Diag(Tok, diag::err_expected_ident); @@ -804,10 +805,13 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, else TUK = Action::TUK_Reference; - if (!Name && !TemplateId && TUK != Action::TUK_Definition) { - // We have a declaration or reference to an anonymous class. - Diag(StartLoc, diag::err_anon_type_definition) - << DeclSpec::getSpecifierName(TagType); + if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error || + TUK != Action::TUK_Definition)) { + if (DS.getTypeSpecType() != DeclSpec::TST_error) { + // We have a declaration or reference to an anonymous class. + Diag(StartLoc, diag::err_anon_type_definition) + << DeclSpec::getSpecifierName(TagType); + } SkipUntil(tok::comma, true); diff --git a/test/SemaTemplate/class-template-id.cpp b/test/SemaTemplate/class-template-id.cpp index df5ef554f7..50e0b00c1a 100644 --- a/test/SemaTemplate/class-template-id.cpp +++ b/test/SemaTemplate/class-template-id.cpp @@ -41,3 +41,7 @@ typedef N::C<float> c2; template<typename T> struct Foo { }; // expected-note{{template is declared here}} void f(void) { Foo bar; } // expected-error{{without a template argument list}} + +// rdar://problem/8254267 +template <typename T> class Party; +template <> class Party<T> { friend struct Party<>; }; // expected-error {{use of undeclared identifier 'T'}} diff --git a/test/SemaTemplate/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp index 1860c7577c..8f4b728181 100644 --- a/test/SemaTemplate/deduction-crash.cpp +++ b/test/SemaTemplate/deduction-crash.cpp @@ -4,7 +4,7 @@ // Note that the error count below doesn't matter. We just want to // make sure that the parser doesn't crash. -// CHECK: 16 errors +// CHECK: 15 errors template<a> struct int_; |