diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 5c5701ac792d..ab66ef3dfdfa 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -578,6 +578,14 @@ Decl *TemplateInstantiator::TransformDecl(Decl *D) { if (TemplateTemplateParmDecl *TTP = dyn_cast(D)) { if (TTP->getDepth() < TemplateArgs.getNumLevels()) { + // If the corresponding template argument is NULL or non-existent, it's + // because we are performing instantiation from explicitly-specified + // template arguments in a function template, but there were some + // arguments left unspecified. + if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(), + TTP->getPosition())) + return D; + TemplateName Template = TemplateArgs(TTP->getDepth(), TTP->getPosition()).getAsTemplate(); assert(!Template.isNull() && Template.getAsTemplateDecl() && @@ -585,14 +593,6 @@ Decl *TemplateInstantiator::TransformDecl(Decl *D) { return Template.getAsTemplateDecl(); } - // If the corresponding template argument is NULL or non-existent, it's - // because we are performing instantiation from explicitly-specified - // template arguments in a function template, but there were some - // arguments left unspecified. - if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(), - TTP->getPosition())) - return D; - // Fall through to find the instantiated declaration for this template // template parameter. } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 6597a853a808..e4017c5630bf 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2159,7 +2159,7 @@ NamedDecl *Sema::FindInstantiatedDecl(NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs) { DeclContext *ParentDC = D->getDeclContext(); if (isa(D) || isa(D) || - isa(D) || isa(D) || + isa(D) || isa(D) || ParentDC->isFunctionOrMethod()) { // D is a local of some kind. Look into the map of local // declarations to their instantiations. diff --git a/clang/test/SemaTemplate/member-function-template.cpp b/clang/test/SemaTemplate/member-function-template.cpp index 5ea8c1010e5c..aea62855c225 100644 --- a/clang/test/SemaTemplate/member-function-template.cpp +++ b/clang/test/SemaTemplate/member-function-template.cpp @@ -73,3 +73,15 @@ void test_incomplete_access(X1 *x1, X2 *x2) { float &fr = x1->get(); (void)x2->get(); // expected-error{{implicit instantiation of undefined template}} } + +// Instantiation of template template parameters in a member function +// template. +namespace TTP { + template struct X { + template class M, class T> void f(const M&); + }; + + template struct Y { }; + + void test_f(X<3> x, Y y) { x.f(y); } +}