diff options
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 8 | ||||
-rw-r--r-- | test/SemaCXX/invalid-template-specifier.cpp | 12 |
2 files changed, 20 insertions, 0 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index d97bc2d028..e9cca9fe1d 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -65,6 +65,12 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, // Parse the optional 'template' keyword, then make sure we have // 'identifier <' after it. if (Tok.is(tok::kw_template)) { + // If we don't have a scope specifier, this isn't a + // nested-name-specifier, since they aren't allowed to start with + // 'template'. + if (!HasScopeSpecifier) + break; + SourceLocation TemplateKWLoc = ConsumeToken(); if (Tok.isNot(tok::identifier)) { @@ -86,6 +92,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, = Actions.ActOnDependentTemplateName(TemplateKWLoc, *Tok.getIdentifierInfo(), Tok.getLocation(), SS); + if (!Template) + break; if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, &SS, TemplateKWLoc, false)) break; diff --git a/test/SemaCXX/invalid-template-specifier.cpp b/test/SemaCXX/invalid-template-specifier.cpp new file mode 100644 index 0000000000..a3f081ff60 --- /dev/null +++ b/test/SemaCXX/invalid-template-specifier.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc %s -verify -fsyntax-only +// PR4809 +// This test is primarily checking that this doesn't crash, not the particular +// diagnostics. + +const template basic_istream<char>; // expected-error {{expected unqualified-id}} + +namespace S {} +template <class X> class Y { + void x() { S::template y<char>(1); } // expected-error {{does not refer to a template}} \ + // expected-error {{no member named 'y'}} +}; |