From: Richard Smith Date: Wed, 10 May 2017 00:01:13 +0000 (+0000) Subject: When instantiating a friend function template, don't forget to inherit default templa... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=23f58ce5d2805d7f2fb9818f04cb7541319a5307;p=clang When instantiating a friend function template, don't forget to inherit default template arguments from other declarations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@302603 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 226bd6055c..03df6fde6c 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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()) diff --git a/test/SemaTemplate/default-arguments.cpp b/test/SemaTemplate/default-arguments.cpp index d3e249db7e..b5b042c64a 100644 --- a/test/SemaTemplate/default-arguments.cpp +++ b/test/SemaTemplate/default-arguments.cpp @@ -207,3 +207,19 @@ Y y2; } // end ns1 } // end ns PR26134 + +namespace friends { + namespace ns { + template struct A { + template friend void f(); + template friend struct X; + }; + template void f(); // expected-warning 0-1{{extension}} + template struct X; + A a; + } + namespace ns { + void g() { f(); } + X *p; + } +}