Only perform an implicit instantiation of a function if its template

specialization kind is TSK_ImplicitInstantiation. Previously, we would
end up implicitly instantiating functions that had explicit
specialization declarations or explicit instantiation declarations
(with no corresponding definitions).

llvm-svn: 83511
This commit is contained in:
Douglas Gregor 2009-10-08 00:14:38 +00:00
parent dafd08ea7e
commit e3dfd4826b
2 changed files with 9 additions and 9 deletions

View File

@ -6198,15 +6198,9 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
// Implicit instantiation of function templates and member functions of
// class templates.
if (!Function->getBody()) {
// FIXME: distinguish between implicit instantiations of function
// templates and explicit specializations (the latter don't get
// instantiated, naturally).
if (Function->getInstantiatedFromMemberFunction() ||
Function->getPrimaryTemplate())
PendingImplicitInstantiations.push_back(std::make_pair(Function, Loc));
}
if (!Function->getBody() &&
Function->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
PendingImplicitInstantiations.push_back(std::make_pair(Function, Loc));
// FIXME: keep track of references to static functions
Function->setUsed(true);

View File

@ -98,6 +98,12 @@ void test_spec(N0::X0<void*> xvp, void *vp) {
namespace N0 {
template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
template<> void X0<const volatile void*>::f1(const volatile void*);
}
void test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) {
x0.f1(cvp); // okay: we've explicitly specialized
}
#if 0