[clang] [Clang][Sema] Convert warning for extraneous template parameter lists to an extension warning (PR #82277)
Krystian Stasiowski via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 20 07:20:50 PST 2024
https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/82277
>From c31ab160b6fb1fb765a885ab3f553437c5768d28 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Mon, 19 Feb 2024 15:36:10 -0500
Subject: [PATCH 1/3] [Clang][Sema] Convert warning for extraneous template
parameter lists to an extension warning
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
clang/lib/Sema/SemaTemplate.cpp | 2 +-
clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p23.cpp | 6 ++----
clang/test/CXX/drs/dr5xx.cpp | 10 ++++------
clang/test/Misc/warning-flags.c | 2 +-
5 files changed, 9 insertions(+), 13 deletions(-)
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/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
>From e2d0e6a47d39a9a81b8659ae46371c76eefde5fa Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 20 Feb 2024 09:59:53 -0500
Subject: [PATCH 2/3] [FOLD]
---
clang/docs/ReleaseNotes.rst | 2 +
.../CXX/temp/temp.spec/temp.expl.spec/p16.cpp | 80 ++++++++++++++++++-
2 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 762e8133f5d536..554321f40347b4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -201,6 +201,8 @@ Improvements to Clang's diagnostics
- Added diagnostics for C11 keywords being incompatible with language standards
before C11, under a new warning group: ``-Wpre-c11-compat``.
+- Clang now diagnoses extraneous template parameter lists as a language extension.
+
Improvements to Clang's time-trace
----------------------------------
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..aa423e95d7fd8f 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,81 @@ 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();
+ };
+
+ 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}}
+}
>From c61e21d2ea111d92e39aa3f329780d59af5a60ff Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 20 Feb 2024 10:20:39 -0500
Subject: [PATCH 3/3] [FOLD]
---
.../CXX/temp/temp.spec/temp.expl.spec/p16.cpp | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
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 aa423e95d7fd8f..c764d3e39ece92 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
@@ -39,7 +39,9 @@ namespace PR10024 {
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}}
@@ -70,6 +72,11 @@ namespace extraneous {
template<typename U>
void h();
+
+ enum class E;
+
+ enum class E;
+ enum F : int;
};
template<>
@@ -113,4 +120,14 @@ namespace extraneous {
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}}
}
More information about the cfe-commits
mailing list