]> granicus.if.org Git - clang/commitdiff
Suppress implicit member redeclarations arising from explicit instantiation
authorJohn McCall <rjmccall@apple.com>
Tue, 2 Mar 2010 23:09:38 +0000 (23:09 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 2 Mar 2010 23:09:38 +0000 (23:09 +0000)
declarations after the member has been explicitly specialized.  We already
did this after explicit instantiation definitions;  not doing it for
declarations meant that subsequent definitions would see a previous
member declaration with specialization kind "explicit instantiation decl",
which would then happily get overridden.

Fixes PR 6458.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97605 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
test/CXX/temp/temp.spec/temp.explicit/p4.cpp

index c10b12b2da1065b323316f58a499b0bb7dc8f057..03219580f92f3ae76df95f7347be4b38a6c24737 100644 (file)
@@ -3790,6 +3790,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
       //   of a template appears after a declaration of an explicit 
       //   specialization for that template, the explicit instantiation has no
       //   effect.
+      SuppressNew = true;
       return false;
         
     case TSK_ExplicitInstantiationDefinition:
index f292b5a93d38068d9dc43b1cfce32c1f3bb61325..2b852136f303776347ebce98f5ef8c7f6e7d24b6 100644 (file)
@@ -30,3 +30,19 @@ template long X0<long>::value;
 
 template<> struct X0<double>;
 template struct X0<double>;
+
+// PR 6458
+namespace test0 {
+  template <class T> class foo {
+    int compare(T x, T y);
+  };
+
+  template <> int foo<char>::compare(char x, char y);
+  template <class T> int foo<T>::compare(T x, T y) {
+    // invalid at T=char; if we get a diagnostic here, we're
+    // inappropriately instantiating this template.
+    void *ptr = x;
+  }
+  extern template class foo<char>;
+  template class foo<char>;
+}