aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-06-17 05:09:08 +0000
committerDouglas Gregor <dgregor@apple.com>2011-06-17 05:09:08 +0000
commit0f9dc86a14068e04e0d2cc6b4ff15eca571236ce (patch)
treeab5151efb40228c125a115dda90813d58623d569
parent751ec9be961888f14342fb63b39bf8727f0dee49 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133236 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/Sema/SemaDecl.cpp15
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp2
3 files changed, 16 insertions, 4 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 7cffa3c3b9..66d940cab9 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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<
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 1d92c162a4..897b01d093 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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)) {
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp
index 52e8ed6d99..cbb439ef5f 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp
@@ -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);