Skip to content

Clang: Add warning flag for storage class specifiers on explicit specializations #96699

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -1535,3 +1535,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">;
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -5366,7 +5366,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">;
Expand Down
16 changes: 12 additions & 4 deletions clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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);
Expand All @@ -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}}
};
3 changes: 1 addition & 2 deletions clang/test/Misc/warning-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions clang/test/SemaCXX/warn-explicit-specialization-storage-class.cpp
Original file line number Diff line number Diff line change
@@ -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}}
Loading