From 33ab0da4b50c0868f0dbbbbb8d018b44acd2bd4d Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sun, 9 Oct 2011 20:59:17 +0000 Subject: [PATCH] A friend template specialization is also dependent if any of its template arguments are dependent. Fixes PR10913. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141515 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 6 +++++- test/CXX/temp/temp.decls/temp.friend/p1.cpp | 24 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 451751f143..5ba38ee9f2 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4987,8 +4987,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // that either the specialized function type or the specialized // template is dependent, and therefore matching will fail. In // this case, don't check the specialization yet. + bool InstantiationDependent = false; if (isFunctionTemplateSpecialization && isFriend && - (NewFD->getType()->isDependentType() || DC->isDependentContext())) { + (NewFD->getType()->isDependentType() || DC->isDependentContext() || + TemplateSpecializationType::anyDependentTemplateArguments( + TemplateArgs.getArgumentArray(), TemplateArgs.size(), + InstantiationDependent))) { assert(HasExplicitTemplateArgs && "friend function specialization without template args"); if (CheckDependentFunctionTemplateSpecialization(NewFD, TemplateArgs, diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp index 578de2952d..63f569be08 100644 --- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp +++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp @@ -332,3 +332,27 @@ namespace test15 { template class B; // expected-note {{in instantiation}} } + +namespace PR10913 { + template class X; + + template void f(X *x) { + x->member = 0; + } + + template void f2(X *x) { + x->member = 0; // expected-error{{'member' is a protected member of 'PR10913::X'}} + } + + template class X { + friend void f(X *x); + friend void f2(X *x); + + protected: + int member; // expected-note{{declared protected here}} + }; + + template void f(X *); + template void f2(X *); + template void f2(X *); // expected-note{{in instantiation of function template specialization 'PR10913::f2' requested here}} +} -- 2.50.1