aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2024-06-27 08:17:40 -0700
committerGitHub <noreply@github.com>2024-06-27 08:17:40 -0700
commita1bce0b89e800cb7ab1d3cf3437f8f34d0695468 (patch)
treef11bc059159990336bac56fcd8f40bc0d94870b7
parentaa24e36d037caee2a4106f721a0ac2ab2a1bc335 (diff)
downloadllvm-a1bce0b89e800cb7ab1d3cf3437f8f34d0695468.zip
llvm-a1bce0b89e800cb7ab1d3cf3437f8f34d0695468.tar.gz
llvm-a1bce0b89e800cb7ab1d3cf3437f8f34d0695468.tar.bz2
Clang: Add warning flag for storage class specifiers on explicit specializations (#96699)
With the recent fix for this situation in class members (#93873) (for which the fixed code is invalid prior to this patch - making migrating code difficult as it must be in lock-step with the compiler migration, if building with -Werror) it'd be really useful to be able to disable this warning during the compiler migration/decouple the compiler migration from the source fixes. In theory this approach will regress the codebase to the previous non-member cases of this issue that were already being held back by the warning (as opposed to if we carved out the new cases into a separate warning from the existing cases) but I think this'll be so rare and the cleanup so simple, that the extra regressions of disabling the warning broadly won't be too much of a problem. (but if folks disagree, I'm open to making the warning more fine-grained)
-rw-r--r--clang/include/clang/Basic/DiagnosticGroups.td4
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp16
-rw-r--r--clang/test/Misc/warning-flags.c3
-rw-r--r--clang/test/SemaCXX/warn-explicit-specialization-storage-class.cpp18
5 files changed, 36 insertions, 7 deletions
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 1c4f305..de99cb4 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1539,3 +1539,7 @@ def BitIntExtension : DiagGroup<"bit-int-extension">;
// Warnings about misuse of ExtractAPI options.
def ExtractAPIMisuse : DiagGroup<"extractapi-misuse">;
+
+// Warnings about using the non-standard extension having an explicit specialization
+// with a storage class specifier.
+def ExplicitSpecializationStorageClass : DiagGroup<"explicit-specialization-storage-class">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0497ffa..96f0c0f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5389,7 +5389,7 @@ def err_not_class_template_specialization : Error<
"cannot specialize a %select{dependent template|template template "
"parameter}0">;
def ext_explicit_specialization_storage_class : ExtWarn<
- "explicit specialization cannot have a storage class">;
+ "explicit specialization cannot have a storage class">, InGroup<ExplicitSpecializationStorageClass>;
def err_dependent_function_template_spec_no_match : Error<
"no candidate function template was found for dependent"
" %select{member|friend}0 function template specialization">;
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp
index f6b5d24..9efa7b6 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,spec %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-explicit-specialization-storage-class %s
// A storage-class-specifier shall not be specified in an explicit
// specialization (14.7.3) or an explicit instantiation (14.7.2)
@@ -7,13 +8,13 @@ template<typename T> void f(T) {}
template<typename T> static void g(T) {}
-template<> static void f<int>(int); // expected-warning{{explicit specialization cannot have a storage class}}
+template<> static void f<int>(int); // spec-warning{{explicit specialization cannot have a storage class}}
template static void f<float>(float); // expected-error{{explicit instantiation cannot have a storage class}}
template<> void f<double>(double);
template void f<long>(long);
-template<> static void g<int>(int); // expected-warning{{explicit specialization cannot have a storage class}}
+template<> static void g<int>(int); // spec-warning{{explicit specialization cannot have a storage class}}
template static void g<float>(float); // expected-error{{explicit instantiation cannot have a storage class}}
template<> void g<double>(double);
@@ -29,5 +30,12 @@ int X<T>::value = 17;
template static int X<int>::value; // expected-error{{explicit instantiation cannot have a storage class}}
-template<> static int X<float>::value; // expected-warning{{explicit specialization cannot have a storage class}}
+template<> static int X<float>::value; // spec-warning{{explicit specialization cannot have a storage class}}
// expected-error@-1{{'static' can only be specified inside the class definition}}
+
+struct t1 {
+ template<typename>
+ static void f1();
+ template<>
+ static void f1<int>(); // spec-warning{{explicit specialization cannot have a storage class}}
+};
diff --git a/clang/test/Misc/warning-flags.c b/clang/test/Misc/warning-flags.c
index dd73331..ae14720 100644
--- a/clang/test/Misc/warning-flags.c
+++ b/clang/test/Misc/warning-flags.c
@@ -18,10 +18,9 @@ This test serves two purposes:
The list of warnings below should NEVER grow. It should gradually shrink to 0.
-CHECK: Warnings without flags (66):
+CHECK: Warnings without flags (65):
CHECK-NEXT: ext_expected_semi_decl_list
-CHECK-NEXT: ext_explicit_specialization_storage_class
CHECK-NEXT: ext_missing_whitespace_after_macro_name
CHECK-NEXT: ext_new_paren_array_nonconst
CHECK-NEXT: ext_plain_complex
diff --git a/clang/test/SemaCXX/warn-explicit-specialization-storage-class.cpp b/clang/test/SemaCXX/warn-explicit-specialization-storage-class.cpp
new file mode 100644
index 0000000..5d9ace2
--- /dev/null
+++ b/clang/test/SemaCXX/warn-explicit-specialization-storage-class.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-explicit-specialization-storage-class -verify=expnone %s
+
+// expnone-no-diagnostics
+
+struct A {
+ template<typename T>
+ static constexpr int x = 0;
+
+ template<>
+ static constexpr int x<void> = 1; // expected-warning{{explicit specialization cannot have a storage class}}
+};
+
+template<typename T>
+static constexpr int x = 0;
+
+template<>
+static constexpr int x<void> = 1; // expected-warning{{explicit specialization cannot have a storage class}}