[clang] 8302cef - [Clang][Sema] Convert warning for extraneous template parameter lists to an extension warning (#82277)

via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 20 10:12:35 PST 2024


Author: Krystian Stasiowski
Date: 2024-02-20T13:12:32-05:00
New Revision: 8302cef83f0614f1fb2078f2335b94aa77bde271

URL: https://github.com/llvm/llvm-project/commit/8302cef83f0614f1fb2078f2335b94aa77bde271
DIFF: https://github.com/llvm/llvm-project/commit/8302cef83f0614f1fb2078f2335b94aa77bde271.diff

LOG: [Clang][Sema] Convert warning for extraneous template parameter lists to an extension warning (#82277)

We currently accept the following explicit specialization with a warning
for the extraneous template parameter list:
```
template<typename T>
void f();

template<>
template<>
void f<int>(); // warning: extraneous template parameter list in template specialization
```

This should really be an extension warning so we reject with
`-pedantic-errors`. This patch converts the warning to an extension
warning.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaTemplate.cpp
    clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p23.cpp
    clang/test/CXX/drs/dr5xx.cpp
    clang/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
    clang/test/Misc/warning-flags.c

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b60ca81b046095..dfc56fc9f6d2c8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -209,6 +209,8 @@ Improvements to Clang's diagnostics
   `WG14 N3029 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3029.htm>`_.
   Fixes `#69352 <https://github.com/llvm/llvm-project/issues/69352>`_.
 
+- Clang now diagnoses extraneous template parameter lists as a language extension.
+
 Improvements to Clang's time-trace
 ----------------------------------
 

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6e3cebc311eeb9..47e892e34260c3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5325,7 +5325,7 @@ def err_alias_template_extra_headers : Error<
 def err_template_spec_extra_headers : Error<
   "extraneous template parameter list in template specialization or "
   "out-of-line template definition">;
-def warn_template_spec_extra_headers : Warning<
+def ext_template_spec_extra_headers : ExtWarn<
   "extraneous template parameter list in template specialization">;
 def note_explicit_template_spec_does_not_need_header : Note<
   "'template<>' header not required for explicitly-specialized class %0 "

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 9e516da2aa27a1..1a975a8d0a0df5 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3667,7 +3667,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
 
     if (!SuppressDiagnostic)
       Diag(ParamLists[ParamIdx]->getTemplateLoc(),
-           AllExplicitSpecHeaders ? diag::warn_template_spec_extra_headers
+           AllExplicitSpecHeaders ? diag::ext_template_spec_extra_headers
                                   : diag::err_template_spec_extra_headers)
           << SourceRange(ParamLists[ParamIdx]->getTemplateLoc(),
                          ParamLists[ParamLists.size() - 2]->getRAngleLoc());

diff  --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p23.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p23.cpp
index 469c4e091953c3..683392c5891538 100644
--- a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p23.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p23.cpp
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -std=c++20 -pedantic-errors -verify %s
 
-// FIXME: This should be an error with -pedantic-errors.
-template<> // expected-warning {{extraneous template parameter list in template specialization}}
+template<> // expected-error {{extraneous template parameter list in template specialization}}
 void f(auto);
 
 template<typename>
@@ -18,7 +17,6 @@ void A<T>::g(auto) { }
 template<>
 void A<int>::g(auto) { }
 
-// FIXME: This should be an error with -pedantic-errors.
 template<>
-template<> // expected-warning {{extraneous template parameter list in template specialization}}
+template<> // expected-error {{extraneous template parameter list in template specialization}}
 void A<long>::g(auto) { }

diff  --git a/clang/test/CXX/drs/dr5xx.cpp b/clang/test/CXX/drs/dr5xx.cpp
index 21a6646d4abcf1..0e1de342f6706f 100644
--- a/clang/test/CXX/drs/dr5xx.cpp
+++ b/clang/test/CXX/drs/dr5xx.cpp
@@ -354,17 +354,15 @@ namespace dr531 { // dr531: partial
 
     template<> void A<char>::f(char) {}
     // expected-error at -1 {{no function template matches function template specialization 'f'}}
-    // FIXME: This is ill-formed; -pedantic-errors should reject.
     template<> template<typename U> void A<char>::g(char, U) {}
-    // expected-warning at -1 {{extraneous template parameter list in template specialization}}
+    // expected-error at -1 {{extraneous template parameter list in template specialization}}
     //   expected-note@#dr531-A-char {{'template<>' header not required for explicitly-specialized class 'dr531::bad::A<char>' declared here}}
     template<> struct A<char>::B {};
     // expected-error at -1 {{extraneous 'template<>' in declaration of struct 'B'}}
     // expected-error at -2 {{specialization of member 'dr531::bad::A<char>::B' does not specialize an instantiated member}}
     //  expected-note@#dr531-B {{attempt to specialize declaration here}}
-    // FIXME: This is ill-formed; -pedantic-errors should reject.
     template<> template<typename U> struct A<char>::C {};
-    // expected-warning at -1 {{extraneous template parameter list in template specialization}}
+    // expected-error at -1 {{extraneous template parameter list in template specialization}}
     //   expected-note@#dr531-A-char {{'template<>' header not required for explicitly-specialized class 'dr531::bad::A<char>' declared here}}
     template<> char A<char>::n = 0;
     // expected-error at -1 {{extraneous 'template<>' in declaration of variable 'n'}}
@@ -808,7 +806,7 @@ namespace dr571 { // dr571 unknown
   int n;
   // FIXME: Test if this has internal linkage.
   const ir r = n;
-  // expected-warning at -1 {{'const' qualifier on reference type 'ir' (aka 'int &') has no effect}} 
+  // expected-warning at -1 {{'const' qualifier on reference type 'ir' (aka 'int &') has no effect}}
 }
 
 namespace dr572 { // dr572: yes
@@ -990,7 +988,7 @@ namespace dr580 { // dr580: partial
       // FIXME: We incorrectly accept this
       // because we think C2::Y::A<...> might
       // instantiate to C2::X::A
-      template<X::I> struct A {}; 
+      template<X::I> struct A {};
     };
   };
 

diff  --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
index c7597e9f817cac..b7c8d3fdfe2649 100644
--- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -pedantic-errors -verify %s
 template<class T> struct A { 
   void f(T);
   template<class X1> void g1(T, X1); 
@@ -36,3 +36,97 @@ namespace PR10024 {
   template <>
   void Test<T>::get<double>(double i) {}  // expected-error{{cannot specialize (with 'template<>') a member of an unspecialized template}}
 }
+
+namespace extraneous {
+  template<typename T> struct A;
+
+  template<typename T> int x;
+
+  template<typename T> void f();
+
+  template<> // expected-error{{extraneous template parameter list in template specialization}}
+  template<>
+  struct A<int>;
+
+  template<> // expected-error{{extraneous template parameter list in template specialization}}
+  template<>
+  int x<int>;
+
+  template<> // expected-error{{extraneous template parameter list in template specialization}}
+  template<>
+  void f<int>();
+
+  template<typename T>
+  struct B {
+    struct C;
+
+    template<typename U>
+    struct D;
+
+    static int y;
+
+    template<typename U>
+    static int z;
+
+    void g();
+
+    template<typename U>
+    void h();
+
+    enum class E;
+
+    enum F : int;
+  };
+
+  template<>
+  template<> // expected-error{{extraneous 'template<>' in declaration of struct 'C'}}
+  struct B<int>::C;
+
+  template<>
+  template<> // expected-error{{extraneous template parameter list in template specialization}}
+  template<>
+  struct B<int>::D<int>;
+
+  template<>
+  template<> // expected-error{{extraneous template parameter list in template specialization}}
+  template<typename U>
+  struct B<int>::D;
+
+  template<>
+  template<> // expected-error{{extraneous 'template<>' in declaration of variable 'y'}}
+  int B<int>::y;
+
+  template<>
+  template<> // expected-error{{extraneous template parameter list in template specialization}}
+  template<>
+  int B<int>::z<int>;
+
+  template<>
+  template<> // expected-error{{extraneous template parameter list in template specialization}}
+  template<typename U>
+  int B<int>::z;
+
+  template<>
+  template<>
+  void B<int>::g(); // expected-error{{no function template matches function template specialization 'g'}}
+
+  template<>
+  template<> // expected-error{{extraneous template parameter list in template specialization}}
+  template<>
+  void B<int>::h<int>();
+
+  template<>
+  template<> // expected-error{{extraneous template parameter list in template specialization}}
+  template<typename U>
+  void B<int>::h<int>(); // expected-error{{function template partial specialization is not allowed}}
+
+  // FIXME: We should diagnose this as having an extraneous 'template<>'
+  template<>
+  template<>
+  enum class B<int>::E; // expected-error{{enumeration cannot be a template}}
+
+  // FIXME: We should diagnose this as having an extraneous 'template<>'
+  template<>
+  template<>
+  enum B<int>::F : int; // expected-error{{enumeration cannot be a template}}
+}

diff  --git a/clang/test/Misc/warning-flags.c b/clang/test/Misc/warning-flags.c
index 07a75046d4e01b..9d4cac9e39b420 100644
--- a/clang/test/Misc/warning-flags.c
+++ b/clang/test/Misc/warning-flags.c
@@ -26,6 +26,7 @@ CHECK-NEXT:   ext_missing_whitespace_after_macro_name
 CHECK-NEXT:   ext_new_paren_array_nonconst
 CHECK-NEXT:   ext_plain_complex
 CHECK-NEXT:   ext_template_arg_extra_parens
+CHECK-NEXT:   ext_template_spec_extra_headers
 CHECK-NEXT:   ext_typecheck_cond_incompatible_operands
 CHECK-NEXT:   ext_typecheck_ordered_comparison_of_pointer_integer
 CHECK-NEXT:   ext_using_undefined_std
@@ -78,7 +79,6 @@ CHECK-NEXT:   warn_register_objc_catch_parm
 CHECK-NEXT:   warn_related_result_type_compatibility_class
 CHECK-NEXT:   warn_related_result_type_compatibility_protocol
 CHECK-NEXT:   warn_template_export_unsupported
-CHECK-NEXT:   warn_template_spec_extra_headers
 CHECK-NEXT:   warn_tentative_incomplete_array
 CHECK-NEXT:   warn_typecheck_function_qualifiers
 CHECK-NEXT:   warn_undef_interface


        


More information about the cfe-commits mailing list