Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -3010,6 +3010,11 @@ return GetTypeOfFunction(S, R, ExplicitSpec); } + DeclAccessPair DAP; + if (FunctionDecl *Viable = + S.resolveAddressOfOnlyViableOverloadCandidate(Arg, DAP)) + return GetTypeOfFunction(S, R, Viable); + return QualType(); } Index: test/SemaCXX/unaddressable-functions.cpp =================================================================== --- test/SemaCXX/unaddressable-functions.cpp +++ test/SemaCXX/unaddressable-functions.cpp @@ -26,3 +26,69 @@ auto ProtStatic = reinterpret_cast(&Protected::checkStatic); // expected-error{{'checkStatic' is a protected member of 'access_control::Protected'}} expected-note@22{{declared protected here}} } + +namespace template_deduction { +void foo() __attribute__((enable_if(false, ""))); + +void bar() __attribute__((enable_if(true, ""))); +void bar() __attribute__((enable_if(false, ""))); + +void baz(int a) __attribute__((enable_if(true, ""))); +void baz(int a) __attribute__((enable_if(a, ""))); +void baz(int a) __attribute__((enable_if(false, ""))); + +void qux(int a) __attribute__((enable_if(1, ""))); +void qux(int a) __attribute__((enable_if(true, ""))); +void qux(int a) __attribute__((enable_if(a, ""))); +void qux(int a) __attribute__((enable_if(false, ""))); + +template void call(Fn F, Args... As) { + F(As...); +} + +void test() { + call(foo); // expected-error{{cannot take address of function 'foo'}} + call(bar); + call(baz, 0); + call(qux, 0); // expected-error{{no matching function for call to 'call'}} expected-note@45{{candidate template ignored: couldn't infer template argument 'Fn'}} + + auto Ptr1 = foo; // expected-error{{cannot take address of function 'foo'}} + auto Ptr2 = bar; + auto Ptr3 = baz; + auto Ptr4 = qux; // expected-error{{variable 'Ptr4' with type 'auto' has incompatible initializer of type ''}} +} + +template +void callMem(Fn F, T t, Args... As) { + (t.*F)(As...); +} + +class Foo { + void bar() __attribute__((enable_if(true, ""))); + void bar() __attribute__((enable_if(false, ""))); + + static void staticBar() __attribute__((enable_if(true, ""))); + static void staticBar() __attribute__((enable_if(false, ""))); +}; + +void testAccess() { + callMem(&Foo::bar, Foo()); // expected-error{{'bar' is a private member of 'template_deduction::Foo'}} expected-note@-8{{implicitly declared private here}} + call(&Foo::staticBar); // expected-error{{'staticBar' is a private member of 'template_deduction::Foo'}} expected-note@-6{{implicitly declared private here}} +} +} + +namespace template_template_deduction { +void foo() __attribute__((enable_if(false, ""))); +template +T foo() __attribute__((enable_if(true, ""))); + +template auto call(Fn F, Args... As) { + return F(As...); +} + +auto Ok = call(&foo); +auto Fail = call(&foo); // expected-error{{no matching function for call to 'call'}} expected-note@-5{{candidate template ignored: couldn't infer template argument 'Fn'}} + +auto PtrOk = &foo; +auto PtrFail = &foo; // expected-error{{variable 'PtrFail' with type 'auto' has incompatible initializer of type ''}} +}