george.burgess.iv updated this revision to Diff 49337. george.burgess.iv added a comment.
- Rebased - Added tests for template type inference - Updated to use machinery introduced by http://reviews.llvm.org/D17701 http://reviews.llvm.org/D15591 Files: lib/Sema/SemaTemplateDeduction.cpp test/SemaCXX/unaddressable-functions.cpp Index: test/SemaCXX/unaddressable-functions.cpp =================================================================== --- test/SemaCXX/unaddressable-functions.cpp +++ test/SemaCXX/unaddressable-functions.cpp @@ -26,3 +26,69 @@ auto ProtStatic = reinterpret_cast<void (*)(char *)>(&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 <typename Fn, typename... Args> 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 '<overloaded function type>'}} +} + +template <typename Fn, typename T, typename... Args> +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 <typename T> +T foo() __attribute__((enable_if(true, ""))); + +template <typename Fn, typename... Args> auto call(Fn F, Args... As) { + return F(As...); +} + +auto Ok = call(&foo<int>); +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<int>; +auto PtrFail = &foo; // expected-error{{variable 'PtrFail' with type 'auto' has incompatible initializer of type '<overloaded function type>'}} +} 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<void (*)(char *)>(&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 <typename Fn, typename... Args> 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 '<overloaded function type>'}} +} + +template <typename Fn, typename T, typename... Args> +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 <typename T> +T foo() __attribute__((enable_if(true, ""))); + +template <typename Fn, typename... Args> auto call(Fn F, Args... As) { + return F(As...); +} + +auto Ok = call(&foo<int>); +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<int>; +auto PtrFail = &foo; // expected-error{{variable 'PtrFail' with type 'auto' has incompatible initializer of type '<overloaded function type>'}} +} 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(); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits