When instantiating a friend function template, don't forget to inherit default template arguments from other declarations.

llvm-svn: 302603
This commit is contained in:
Richard Smith 2017-05-10 00:01:13 +00:00
parent 3388f7c0cb
commit f3597653fb
2 changed files with 29 additions and 0 deletions

View File

@ -1849,6 +1849,19 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
}
}
}
// Check the template parameter list against the previous declaration. The
// goal here is to pick up default arguments added since the friend was
// declared; we know the template parameter lists match, since otherwise
// we would not have picked this template as the previous declaration.
if (TemplateParams && FunctionTemplate->getPreviousDecl()) {
SemaRef.CheckTemplateParameterList(
TemplateParams,
FunctionTemplate->getPreviousDecl()->getTemplateParameters(),
Function->isThisDeclarationADefinition()
? Sema::TPC_FriendFunctionTemplateDefinition
: Sema::TPC_FriendFunctionTemplate);
}
}
if (Function->isLocalExternDecl() && !Function->getPreviousDecl())

View File

@ -207,3 +207,19 @@ Y<false> y2;
} // end ns1
} // end ns PR26134
namespace friends {
namespace ns {
template<typename> struct A {
template<typename> friend void f();
template<typename> friend struct X;
};
template<typename = int> void f(); // expected-warning 0-1{{extension}}
template<typename = int> struct X;
A<int> a;
}
namespace ns {
void g() { f(); }
X<int> *p;
}
}