r359740 - Consume unexpected "template" keywords after "using"

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Wed May 1 16:33:50 PDT 2019


Author: rtrieu
Date: Wed May  1 16:33:49 2019
New Revision: 359740

URL: http://llvm.org/viewvc/llvm-project?rev=359740&view=rev
Log:
Consume unexpected "template" keywords after "using"

The parser was dealing with unexpected "template" keywords after "using"
keywords too late and putting the parser into the wrong state, which could
lead to a crash down the line.  This change allows the parser to consume the
bad "template" keywords earlier, and continue parsing as if "template" was
never there to begin with for better error recovery.

Added:
    cfe/trunk/test/Parser/using-template.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=359740&r1=359739&r2=359740&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed May  1 16:33:49 2019
@@ -683,6 +683,8 @@ def err_id_after_template_in_nested_name
   "expected template name after 'template' keyword in nested name specifier">;
 def err_unexpected_template_in_unqualified_id : Error<
   "'template' keyword not permitted here">;
+def err_unexpected_template_after_using : Error<
+  "'template' keyword not permitted after 'using' keyword">;
 def err_two_right_angle_brackets_need_space : Error<
   "a space is required between consecutive right angle brackets (use '> >')">;
 def err_right_angle_bracket_equal_needs_space : Error<

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=359740&r1=359739&r2=359740&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed May  1 16:33:49 2019
@@ -474,6 +474,13 @@ Parser::ParseUsingDirectiveOrDeclaration
     return nullptr;
   }
 
+  // Consume unexpected 'template' keywords.
+  while (Tok.is(tok::kw_template)) {
+    SourceLocation TemplateLoc = ConsumeToken();
+    Diag(TemplateLoc, diag::err_unexpected_template_after_using)
+        << FixItHint::CreateRemoval(TemplateLoc);
+  }
+
   // 'using namespace' means this is a using-directive.
   if (Tok.is(tok::kw_namespace)) {
     // Template parameters are always an error here.
@@ -2542,6 +2549,13 @@ Parser::ParseCXXClassMemberDeclaration(A
     // Eat 'using'.
     SourceLocation UsingLoc = ConsumeToken();
 
+    // Consume unexpected 'template' keywords.
+    while (Tok.is(tok::kw_template)) {
+      SourceLocation TemplateLoc = ConsumeToken();
+      Diag(TemplateLoc, diag::err_unexpected_template_after_using)
+          << FixItHint::CreateRemoval(TemplateLoc);
+    }
+
     if (Tok.is(tok::kw_namespace)) {
       Diag(UsingLoc, diag::err_using_namespace_in_class);
       SkipUntil(tok::semi, StopBeforeMatch);

Added: cfe/trunk/test/Parser/using-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/using-template.cpp?rev=359740&view=auto
==============================================================================
--- cfe/trunk/test/Parser/using-template.cpp (added)
+++ cfe/trunk/test/Parser/using-template.cpp Wed May  1 16:33:49 2019
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 %s -verify
+
+namespace N1 {
+template <typename... Ts>
+struct Foo {
+  template <typename T>
+  struct Bar {
+    static constexpr bool is_present = false;
+  };
+};
+
+template <typename T, typename... Ts>
+struct Foo<T, Ts...> : public Foo<Ts...> {
+  using template Foo<Ts...>::Bar;
+  // expected-error at -1 {{'template' keyword not permitted after 'using' keyword}}
+};
+}
+
+namespace N2 {
+namespace foo {
+  using I = int;
+}
+using template namespace foo;
+// expected-error at -1 {{'template' keyword not permitted after 'using' keyword}}
+using template template namespace foo;
+// expected-error at -1 2{{'template' keyword not permitted after 'using' keyword}}
+I i;
+}
+
+namespace N3 {
+namespace foo {
+  using I = int;
+}
+using template foo::I;
+// expected-error at -1 {{'template' keyword not permitted after 'using' keyword}}
+I i;
+}
+
+namespace N4 {
+template <typename T>
+class A {};
+
+template <typename T>
+using B = A<T>;
+B<int> b;
+
+using template <typename T> C = A<T>;
+// expected-error at -1 {{'template' keyword not permitted after 'using' keyword}}
+// expected-error at -2 {{expected unqualified-id}}
+C<int> c;
+// expected-error at -1 {{no template named 'C'}}
+}




More information about the cfe-commits mailing list