From: John McCall Date: Tue, 2 Mar 2010 23:09:38 +0000 (+0000) Subject: Suppress implicit member redeclarations arising from explicit instantiation X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e97c32f9578861d575ca96bbbae426c76cbc9024;p=clang Suppress implicit member redeclarations arising from explicit instantiation 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 --- diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index c10b12b2da..03219580f9 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -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: diff --git a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp index f292b5a93d..2b852136f3 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp @@ -30,3 +30,19 @@ template long X0::value; template<> struct X0; template struct X0; + +// PR 6458 +namespace test0 { + template class foo { + int compare(T x, T y); + }; + + template <> int foo::compare(char x, char y); + template int foo::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; + template class foo; +}