]> granicus.if.org Git - clang/commitdiff
When an explicit specialization has a storage specifier, error if that
authorDouglas Gregor <dgregor@apple.com>
Fri, 17 Jun 2011 05:09:08 +0000 (05:09 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 17 Jun 2011 05:09:08 +0000 (05:09 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp

index 7cffa3c3b90625a4c75330403f903892cbef5d9a..66d940cab919420dbde9744aaa49886ff28f7527 100644 (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<
index 1d92c162a4ec7a1206e1b7e4805975bf2a072f50..897b01d09319ae22ab2a546e973d44489322b3e0 100644 (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)) {
index 52e8ed6d99a905225c3e8dc93eb0b2d9dad4ff3b..cbb439ef5fecde54976b81f11d18c6064115de9c 100644 (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);