Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang] require template arg list after template kw #80801

Merged
merged 8 commits into from
May 31, 2024

Conversation

evelez7
Copy link
Contributor

@evelez7 evelez7 commented Feb 6, 2024

Require a template argument list after an identifier prefixed by the template keyword. Introduced by CWG 96, but the current wording of [temp.names]p5 was introduced in P1787R6, and became [temp.names]p6 somewhere else.

Fixes #53095

@evelez7 evelez7 requested a review from Endilll as a code owner February 6, 2024 05:46
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Feb 6, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 6, 2024

@llvm/pr-subscribers-clang

Author: Erick Velez (evelez7)

Changes

Require a template argument list after an identifier prefixed by the template keyword. Introduced by [CWG 96](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#96). Current wording of [temp.names] introduced in P1787R6.

Fixes #53095


Full diff: https://github.com/llvm/llvm-project/pull/80801.diff

8 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+3)
  • (modified) clang/lib/Parse/ParseExprCXX.cpp (+17-6)
  • (modified) clang/test/CXX/drs/dr0xx.cpp (+1-1)
  • (modified) clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp (+3-3)
  • (modified) clang/test/SemaCXX/template-specialization.cpp (+1-1)
  • (modified) clang/test/SemaTemplate/dependent-names.cpp (+3-3)
  • (modified) clang/test/SemaTemplate/template-id-expr.cpp (+18-18)
  • (modified) clang/test/SemaTemplate/template-id-printing.cpp (-13)
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index a30ab27566ec3e..159600f3e26dc0 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -868,6 +868,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index fd262ff31e661a..b3a1a6f6cf80d0 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -2995,13 +2996,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
           SS, ObjectType, ObjectHadErrors,
           TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
           EnteringContext, Result, TemplateSpecified);
-    else if (TemplateSpecified &&
-             Actions.ActOnTemplateName(
-                 getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
-                 EnteringContext, Template,
-                 /*AllowInjectedClassName*/ true) == TNK_Non_template)
-      return true;
 
+    if (TemplateSpecified) {
+      TemplateNameKind TNK =
+          Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+                                    ObjectType, EnteringContext, Template,
+                                    /*AllowInjectedClassName*/ true);
+      if (TNK == TNK_Non_template)
+        return true;
+
+      // C++ [template.names]p6
+      // A name prefixed by the keyword template shall be followed by a template
+      // argument list or refer to a class template or an alias template.
+      if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name ||
+           TNK == TNK_Var_template) &&
+          !Tok.is(tok::less))
+        Diag(IdLoc, diag::err_missing_template_arg_list_after_template_kw);
+    }
     return false;
   }
 
diff --git a/clang/test/CXX/drs/dr0xx.cpp b/clang/test/CXX/drs/dr0xx.cpp
index 5959f0a0c8dd65..127d45be5bda97 100644
--- a/clang/test/CXX/drs/dr0xx.cpp
+++ b/clang/test/CXX/drs/dr0xx.cpp
@@ -1414,7 +1414,7 @@ namespace dr96 { // dr96: no
     // FIXME: This is ill-formed, because 'f' is not a template-id and does not
     // name a class template.
     // FIXME: What about alias templates?
-    int k2 = a.template f(1);
+    int k2 = a.template f(1); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
     A::template S<int> s;
     B<A::template S> b;
   }
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index af121a8b75d512..37dbe0b212eb6a 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
   struct A {
     template<int = 0> static int n; // expected-note 2{{here}}
   };
-  int &r = A::template n; // expected-error {{use of variable template 'n' requires template arguments}}
+  int &r = A::template n; // expected-error {{use of variable template 'n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 
   template<typename T>
-  int &f() { return T::template n; } // expected-error {{use of variable template 'n' requires template arguments}}
+  int &f() { return T::template n; } // expected-error {{use of variable template 'n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
   int &s = f<A>(); // expected-note {{instantiation of}}
 
   namespace B {
     template<int = 0> static int n; // expected-note {{here}}
   }
-  int &t = B::template n; // expected-error {{use of variable template 'n' requires template arguments}}
+  int &t = B::template n; // expected-error {{use of variable template 'n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 
   struct C {
     template <class T> static T G;
diff --git a/clang/test/SemaCXX/template-specialization.cpp b/clang/test/SemaCXX/template-specialization.cpp
index 7b26ff9f5c5ba4..c57ca51538d8f9 100644
--- a/clang/test/SemaCXX/template-specialization.cpp
+++ b/clang/test/SemaCXX/template-specialization.cpp
@@ -11,7 +11,7 @@ struct B {
   template <int i>
   static void foo() {
     int array[i];
-    A::template bar(array[0]); // expected-error {{no matching function for call to 'bar'}}
+    A::template bar(array[0]); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}} expected-error {{no matching function for call to 'bar'}}
   }
 };
 
diff --git a/clang/test/SemaTemplate/dependent-names.cpp b/clang/test/SemaTemplate/dependent-names.cpp
index 641ec950054f57..5026004cdcc0c2 100644
--- a/clang/test/SemaTemplate/dependent-names.cpp
+++ b/clang/test/SemaTemplate/dependent-names.cpp
@@ -418,7 +418,7 @@ template <typename> struct CT2 {
 template <typename T> int CT2<int>::X<>; // expected-error {{template parameter list matching the non-templated nested type 'CT2<int>' should be empty}}
 
 namespace DependentTemplateIdWithNoArgs {
-  template<typename T> void f() { T::template f(); }
+  template<typename T> void f() { T::template f(); } // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
   struct X {
     template<int = 0> static void f();
   };
@@ -429,7 +429,7 @@ namespace DependentUnresolvedUsingTemplate {
   template<typename T>
   struct X : T {
     using T::foo;
-    void f() { this->template foo(); } // expected-error {{does not refer to a template}}
+    void f() { this->template foo(); } // expected-error {{does not refer to a template}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
     void g() { this->template foo<>(); } // expected-error {{does not refer to a template}}
     void h() { this->template foo<int>(); } // expected-error {{does not refer to a template}}
   };
@@ -448,7 +448,7 @@ namespace DependentUnresolvedUsingTemplate {
 namespace PR37680 {
   template <class a> struct b : a {
     using a::add;
-    template<int> int add() { return this->template add(0); }
+    template<int> int add() { return this->template add(0); } // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
   };
   struct a {
     template<typename T = void> int add(...);
diff --git a/clang/test/SemaTemplate/template-id-expr.cpp b/clang/test/SemaTemplate/template-id-expr.cpp
index 0555d8b94504fb..3f1e889d78eeec 100644
--- a/clang/test/SemaTemplate/template-id-expr.cpp
+++ b/clang/test/SemaTemplate/template-id-expr.cpp
@@ -65,11 +65,11 @@ struct Y0 {
   template<typename U>
   void f() {
     Y0::template f1<U>(0);
-    Y0::template f1(0);
-    this->template f1(0);
+    Y0::template f1(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
+    this->template f1(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 
     Y0::template f2<U>(0);
-    Y0::template f2(0);
+    Y0::template f2(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 
     Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
     Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
@@ -77,11 +77,11 @@ struct Y0 {
     int x;
     x = Y0::f4(0);
     x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
-    x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+    x = Y0::template f4(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}} expected-error {{assigning to 'int' from incompatible type 'void'}}
 
     x = this->f4(0);
     x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
-    x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+    x = this->template f4(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}} expected-error {{assigning to 'int' from incompatible type 'void'}}
   }
 };
 
@@ -109,11 +109,11 @@ struct Y1 {
   template<typename U>
   void f() {
     Y1::template f1<U>(0);
-    Y1::template f1(0);
-    this->template f1(0);
+    Y1::template f1(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
+    this->template f1(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 
     Y1::template f2<U>(0);
-    Y1::template f2(0);
+    Y1::template f2(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 
     Y1::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
     Y1::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
@@ -121,11 +121,11 @@ struct Y1 {
     int x;
     x = Y1::f4(0);
     x = Y1::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
-    x = Y1::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+    x = Y1::template f4(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}} expected-error {{assigning to 'int' from incompatible type 'void'}}
 
     x = this->f4(0);
     x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
-    x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+    x = this->template f4(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}} expected-error {{assigning to 'int' from incompatible type 'void'}}
   }
 };
 
@@ -138,23 +138,23 @@ struct Y2 : Y1<T> {
   template<typename U>
   void f(Y1 *p) {
     Y1::template f1<U>(0);
-    Y1::template f1(0);
-    p->template f1(0);
+    Y1::template f1(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
+    p->template f1(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 
     Y1::template f2<U>(0);
-    Y1::template f2(0);
+    Y1::template f2(0); // expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 
-    Y1::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
-    Y1::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
+    Y1::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
+    Y1::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 
     int x;
     x = Y1::f4(0);
     x = Y1::f4<int>(0); // expected-error {{use 'template'}} expected-error {{assigning to 'int' from incompatible type 'void'}}
-    x = Y1::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+    x = Y1::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 
     x = p->f4(0);
     x = p->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} expected-error {{use 'template'}}
-    x = p->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+    x = p->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
   }
 };
 
@@ -169,7 +169,7 @@ struct A {
 
 template<int I>
 void f5() {
-  A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}}
+  A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
 }
 
 template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}}
diff --git a/clang/test/SemaTemplate/template-id-printing.cpp b/clang/test/SemaTemplate/template-id-printing.cpp
index 047589b1ce4333..e004bd35e5a0c3 100644
--- a/clang/test/SemaTemplate/template-id-printing.cpp
+++ b/clang/test/SemaTemplate/template-id-printing.cpp
@@ -99,8 +99,6 @@ template <typename T>
 void test() {
   // CHECK: S<T>::foo;
   S<T>::foo;
-  // CHECK: S<T>::template foo;
-  S<T>::template foo;
   // CHECK: S<T>::template foo<>;
   S<T>::template foo<>;
   // CHECK: S<T>::template foo<T>;
@@ -121,8 +119,6 @@ void test() {
   S<T> s;
   // CHECK: s.foo;
   s.foo;
-  // CHECK: s.template foo;
-  s.template foo;
   // CHECK: s.template foo<>;
   s.template foo<>;
   // CHECK: s.template foo<T>;
@@ -130,12 +126,3 @@ void test() {
 }
 
 } // namespace DSME
-
-namespace DSDRE_withImplicitTemplateArgs {
-
-template <typename T> void foo() {
-  // CHECK: T::template bar();
-  T::template bar();
-}
-
-} // namespace DSDRE_withImplicitTemplateArgs

Copy link
Contributor

@Endilll Endilll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you picking this up!

Since this patch seems to implement current take of the Standard on CWG96, you should change // dr96: no to // dr96: sup P1787 at dr0xx.cpp:1403, and then run clang/www/make_cxx_dr_status script to regenerate cxx_dr_status.html. While this status is not officially recognized (at least yet), it's the only one that makes sense for CWG96 now.

You should also mention in the description that CWG96 resolution from Feb 2010 is superseded by changes to [temp.names]/5 introduced by P1787R6, to make it easier for people to find exact wording in that gigantic paper.

@@ -1414,7 +1414,7 @@ namespace dr96 { // dr96: no
// FIXME: This is ill-formed, because 'f' is not a template-id and does not
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this FIXME is superseded by P1787R6, the same way 2010 resolution is.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what direction of "superseded" you mean here, but (except for the separable alias-template bit) the comment is simply correct (since CWG96; before that any template would do). All that P1787R6 did here was correct the strange use of "name" to refer to (among other things) a template-id and deprecate the T::template NestedTypeTemplate case.

Copy link
Contributor

@Endilll Endilll Feb 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@opensdh Thank you for the clarification. I guess I read N1528 the wrong way.
Would it be a correct statement to make that you deprecated the following case described in that paper?

Consequently, the recommendation of this paper is: If the template keyword is followed by a name that does not have a template-argument-list, the name must refer to a class template and be used in a context in which a class template is valid, otherwise the program is ill-formed.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, P1787R6 deprecated that use case; you're supposed to just not use template there. This is consistent with the recommendation in N1528, but of course we now reject the premise that template is needed for a template template argument. The reasoning, if it helps, is that compilers already have to deal with ambiguity there:

template<auto> void f();                                // #1
template<class> void f(int=0);                          // #2
template<template<class> class> void f(void*=nullptr);  // #3

template<class T> void g() {
  // in C++20, [temp.res]/6 and [temp.arg.template]/1 contradict each other here:
  f<T::Q>();             // could be #1 or #3
}
template<class T> struct X {
  // OK per [temp.local]/1
  void h() {f<X>(T());}  // could be #2 or #3
  void i() {T::template R<X>();}  // could be anything
}

Accordingly, CWG1478's question was answered in the negative, and template (is to be) restricted to the case where it influences the interpretation of a <.

@@ -1414,7 +1414,7 @@ namespace dr96 { // dr96: no
// FIXME: This is ill-formed, because 'f' is not a template-id and does not
// name a class template.
// FIXME: What about alias templates?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, what about alias templates? My guess is that new rules work for them as well: no template argument list — no template.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of 'template' before an alias template is deprecated, along with before a class template. I wasn't sure how to interpret this for clang, they aren't errors yet?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alias template case was aligned with the class-template case as part of CWG1710.

clang/test/CXX/drs/dr0xx.cpp Outdated Show resolved Hide resolved
@evelez7
Copy link
Contributor Author

evelez7 commented Feb 8, 2024

I was wondering why the Windows CI was failing but seems to be bugged according to Discourse. Newest commit changes the error to a pedantic warning that defaults to an error.

Handled the pedantic warning properly by putting it in its own diagnostic group as an extension. Thanks to Aaron Ballman.

@evelez7
Copy link
Contributor Author

evelez7 commented Mar 26, 2024

ping

@evelez7
Copy link
Contributor Author

evelez7 commented May 23, 2024

ping @Endilll

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this! The changes should also come with a release note in clang/docs/ReleaseNotes.rst so users know about the change.

// C++ [template.names]p6
// A name prefixed by the keyword template shall be followed by a template
// argument list or refer to a class template or an alias template.
if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about type templates: https://godbolt.org/z/1coGTT38P (hmm we may have a wider issue there, from looking at Clang's current behavior, so a FIXME would be reasonable too).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this case isn't covered here. The error fires before reaching this method. I can try to diagnose it for this patch if needed, or I can do a followup patch.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's reasonable to handle in a follow-up, thanks!

@evelez7 evelez7 force-pushed the clang-not-template-after-keyword branch from 2375746 to 1e0ecee Compare May 30, 2024 07:12
evelez7 and others added 2 commits May 30, 2024 00:15
Co-authored-by: Shafik Yaghmour <shafik.yaghmour@intel.com>
clang/test/CXX/drs/cwg0xx.cpp Outdated Show resolved Hide resolved
clang/docs/ReleaseNotes.rst Outdated Show resolved Hide resolved
clang/lib/Parse/ParseExprCXX.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changes are reasonable, but I'd like to wait a bit before landing to give @erichkeane a chance to review as templates code owner.

// C++ [template.names]p6
// A name prefixed by the keyword template shall be followed by a template
// argument list or refer to a class template or an alias template.
if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's reasonable to handle in a follow-up, thanks!

@evelez7 evelez7 merged commit f46d146 into llvm:main May 31, 2024
5 of 7 checks passed
HendrikHuebner pushed a commit to HendrikHuebner/llvm-project that referenced this pull request Jun 2, 2024
Require a template argument list after an identifier prefixed by the
template keyword. Introduced by [CWG
96](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#96),
but the current wording of
[[temp.names]p5](https://eel.is/c++draft/temp.names#6) was introduced in
[P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html),
and became [temp.names]p6 somewhere else.

Fixes llvm#53095

---------

Co-authored-by: Shafik Yaghmour <shafik.yaghmour@intel.com>
searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Jun 2, 2024
Revert: breaks composable kernel build
f46d146 [clang] require template arg list after template kw (llvm#80801)

Change-Id: I5e85213cedec32084ebf573a410a0b75393c6721
@evelez7 evelez7 deleted the clang-not-template-after-keyword branch June 3, 2024 05:13
DavidSpickett added a commit to DavidSpickett/llvm-project that referenced this pull request Jun 3, 2024
Since llvm#80801 clang requires
a template argument list after the use of the template keyword.

https://lab.llvm.org/buildbot/#/builders/176/builds/10230

error: a template argument list is expected after a name prefixed by the template keyword [-Wmissing-template-arg-list-after-template-kw]

This fixes the instances found by the AArch64 Linux builds.
DavidSpickett added a commit that referenced this pull request Jun 3, 2024
…#94204)

Since #80801 clang requires a
template argument list after the use of the template keyword.

https://lab.llvm.org/buildbot/#/builders/176/builds/10230

error: a template argument list is expected after a name prefixed by the
template keyword [-Wmissing-template-arg-list-after-template-kw]

This fixes the instances found by the AArch64 Linux builds.
bherrera pushed a commit to misttech/mist-os that referenced this pull request Jun 3, 2024
llvm/llvm-project#80801 started
requiring template arg list after template keyword, which
caused issues in our codebase. This patch suppresses
that warning to fix the Clang toolchain canary builders.

Bug: 344080745
Change-Id: I328d05f3e504b8806dae417142a109504441bf66
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1058727
Reviewed-by: Haowei Wu <haowei@google.com>
Reviewed-by: Roland McGrath <mcgrathr@google.com>
Commit-Queue: Gulfem Savrun Yeniceri <gulfem@google.com>
Fuchsia-Auto-Submit: Gulfem Savrun Yeniceri <gulfem@google.com>
Reviewed-by: Petr Hosek <phosek@google.com>
aeubanks added a commit to aeubanks/grpc that referenced this pull request Jun 4, 2024
The template keyword should only be used if we have angle brackets after the method.

Fixes code broken by upcoming clang change: llvm/llvm-project#80801
aeubanks added a commit to aeubanks/grpc that referenced this pull request Jun 4, 2024
The template keyword should only be used if we have angle brackets after the method.

Fixes code broken by upcoming clang change: llvm/llvm-project#80801
BertalanD added a commit to BertalanD/ladybird that referenced this pull request Jun 4, 2024
These were made invalid with P1787, and Clang (19) trunk started warning
on them with llvm/llvm-project#80801.
artem pushed a commit to artem/fuchsia-mirror that referenced this pull request Jun 5, 2024
llvm/llvm-project#80801 started
requiring template arg list after template keyword, which
caused issues in our codebase. This patch suppresses
that warning to fix the Clang toolchain canary builders.

Bug: 344080745
Change-Id: I328d05f3e504b8806dae417142a109504441bf66
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1058727
Reviewed-by: Haowei Wu <haowei@google.com>
Reviewed-by: Roland McGrath <mcgrathr@google.com>
Commit-Queue: Gulfem Savrun Yeniceri <gulfem@google.com>
Fuchsia-Auto-Submit: Gulfem Savrun Yeniceri <gulfem@google.com>
Reviewed-by: Petr Hosek <phosek@google.com>
copybara-service bot pushed a commit to grpc/grpc that referenced this pull request Jun 5, 2024
…#36805)

Clang now requires a template argument list after the use of the template keyword. Edit this
instance to remove the template keyword since there are no template arguments.

See llvm/llvm-project#80801.

Closes #36805

COPYBARA_INTEGRATE_REVIEW=#36805 from amykhuang:master 6f385be
PiperOrigin-RevId: 640554705
vedantparanjape-amd pushed a commit to vedantparanjape-amd/llvm-project that referenced this pull request Jun 7, 2024
…llvm#94204)

Since llvm#80801 clang requires a
template argument list after the use of the template keyword.

https://lab.llvm.org/buildbot/#/builders/176/builds/10230

error: a template argument list is expected after a name prefixed by the
template keyword [-Wmissing-template-arg-list-after-template-kw]

This fixes the instances found by the AArch64 Linux builds.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

.template not followed by template arguments is incorrectly accepted
8 participants