Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -3803,10 +3803,17 @@ return Result; } + // Capture the context in which the function call is made. This is the context + // that is needed when the accessibility of a class member used as a template + // argument is checked. + DeclContext *CallingCtx = CurContext; + return FinishTemplateArgumentDeduction( FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info, - &OriginalCallArgs, PartialOverloading, - [&]() { return CheckNonDependent(ParamTypesForArgChecking); }); + &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() { + ContextRAII SavedContext(*this, CallingCtx); + return CheckNonDependent(ParamTypesForArgChecking); + }); } QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, Index: test/SemaCXX/access.cpp =================================================================== --- test/SemaCXX/access.cpp +++ test/SemaCXX/access.cpp @@ -169,3 +169,50 @@ } void bar() { foo(); } } + +namespace OverloadedMemberFunctionPointer { + template + void func0() {} + + template + void func1() {} + + template + void func2(void(*fn)()) {} // expected-note 2 {{candidate function not viable: no overload of 'func}} + + class C { + private: + friend void friendFunc(); + void overloadedMethod(); + protected: + void overloadedMethod(int); + public: + void overloadedMethod(int, int); + void method() { + func2(&func0); + func2(&func1); + } + }; + + void friendFunc() { + func2(&func0); + func2(&func1); + } + + void nonFriendFunc() { + func2(&func0); // expected-error {{no matching function for call to 'func2'}} + func2(&func1); // expected-error {{no matching function for call to 'func2'}} + } + + // r325321 caused an assertion failure when the following code was compiled. + class A { + template static bool foo1() { return true; } + + public: + void init(bool c) { + if (c) { + auto f = foo1; + } + } + }; +}