When an explicit specialization has a storage specifier, error if that

storage specifier is different from the storage specifier on the
template. If that storage specifier is the same, then we only warn.

Thanks to John for the prodding.

llvm-svn: 133236
This commit is contained in:
Douglas Gregor 2011-06-17 05:09:08 +00:00
parent 9b71f0cfac
commit 84265a09d6
3 changed files with 16 additions and 4 deletions

View File

@ -1914,6 +1914,9 @@ def err_function_specialization_in_class : Error<
"cannot specialize a function %0 within class scope">;
def ext_explicit_specialization_storage_class : ExtWarn<
"explicit specialization cannot have a storage class">;
def err_explicit_specialization_inconsistent_storage_class : Error<
"explicit specialization has extraneous, inconsistent storage class "
"'%select{none|extern|static|__private_extern__|auto|register}0'">;
// C++ class template specializations and out-of-line definitions
def err_template_spec_needs_header : Error<

View File

@ -4662,9 +4662,18 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// A storage-class-specifier shall not be specified in an explicit
// specialization (14.7.3)
if (SC != SC_None) {
Diag(NewFD->getLocation(),
diag::ext_explicit_specialization_storage_class)
<< FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
if (SC != NewFD->getStorageClass())
Diag(NewFD->getLocation(),
diag::err_explicit_specialization_inconsistent_storage_class)
<< SC
<< FixItHint::CreateRemoval(
D.getDeclSpec().getStorageClassSpecLoc());
else
Diag(NewFD->getLocation(),
diag::ext_explicit_specialization_storage_class)
<< FixItHint::CreateRemoval(
D.getDeclSpec().getStorageClassSpecLoc());
}
} else if (isExplicitSpecialization && isa<CXXMethodDecl>(NewFD)) {

View File

@ -7,7 +7,7 @@ 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); // expected-error{{explicit specialization has extraneous, inconsistent storage class 'static'}}
template static void f<float>(float); // expected-error{{explicit instantiation cannot have a storage class}}
template<> void f<double>(double);