ahatanak updated this revision to Diff 138066. ahatanak added a comment. The new patch passes the calling context to CheckNonDependent so that Sema::CheckAddressOfMemberAccess uses the correct context to check accessibility of explicit template arguments. I initially tried moving the declaration of SavedContext in Sema::FinishTemplateArgumentDeduction to after the call to CheckNonDependent, but that caused test/SemaCXX/cxx1z-class-template-argument-deduction.cpp to fail. It seems like it changes the way lookup of default template arguments is done when the context (which is a CXXDeductionGuideDecl in the failing test case) is not set before ConvertDeducedTemplateArguments is called.
https://reviews.llvm.org/D36918 Files: include/clang/Sema/Sema.h lib/Sema/SemaTemplateDeduction.cpp test/SemaCXX/access.cpp
Index: test/SemaCXX/access.cpp =================================================================== --- test/SemaCXX/access.cpp +++ test/SemaCXX/access.cpp @@ -169,3 +169,38 @@ } void bar() { foo<void>(); } } + +namespace OverloadedMemberFunctionPointer { + template<class T, void(T::*pMethod)()> + void func0() {} + + template<class T, void(T::*pMethod)(int)> + void func1() {} + + template<class T> + 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<int>(&func0<C, &C::overloadedMethod>); + func2<int>(&func1<C, &C::overloadedMethod>); + } + }; + + void friendFunc() { + func2<int>(&func0<C, &C::overloadedMethod>); + func2<int>(&func1<C, &C::overloadedMethod>); + } + + void nonFriendFunc() { + func2<int>(&func0<C, &C::overloadedMethod>); // expected-error {{no matching function for call to 'func2'}} + func2<int>(&func1<C, &C::overloadedMethod>); // expected-error {{no matching function for call to 'func2'}} + } +} Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -3170,7 +3170,8 @@ unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, TemplateDeductionInfo &Info, SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs, - bool PartialOverloading, llvm::function_ref<bool()> CheckNonDependent) { + bool PartialOverloading, + llvm::function_ref<bool(DeclContext *)> CheckNonDependent) { // Unevaluated SFINAE context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); @@ -3185,6 +3186,7 @@ if (Inst.isInvalid()) return TDK_InstantiationDepth; + DeclContext *CallingCtx = CurContext; ContextRAII SavedContext(*this, FunctionTemplate->getTemplatedDecl()); // C++ [temp.deduct.type]p2: @@ -3206,7 +3208,7 @@ // P with a type that was non-dependent before substitution of any // explicitly-specified template arguments, if the corresponding argument // A cannot be implicitly converted to P, deduction fails. - if (CheckNonDependent()) + if (CheckNonDependent(CallingCtx)) return TDK_NonDependentConversionFailure; // Form the template argument list from the deduced template arguments. @@ -3799,8 +3801,10 @@ return FinishTemplateArgumentDeduction( FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info, - &OriginalCallArgs, PartialOverloading, - [&]() { return CheckNonDependent(ParamTypesForArgChecking); }); + &OriginalCallArgs, PartialOverloading, [&](DeclContext *CallingCtx) { + ContextRAII SavedContext(*this, CallingCtx); + return CheckNonDependent(ParamTypesForArgChecking); + }); } QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -6927,7 +6927,8 @@ sema::TemplateDeductionInfo &Info, SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr, bool PartialOverloading = false, - llvm::function_ref<bool()> CheckNonDependent = []{ return false; }); + llvm::function_ref<bool(DeclContext *)> CheckNonDependent = + [](DeclContext *){ return false; }); TemplateDeductionResult DeduceTemplateArguments( FunctionTemplateDecl *FunctionTemplate,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits