r263888 - [Sema] Make type deduction work with some overloadable functions

George Burgess IV via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 19 14:51:45 PDT 2016


Author: gbiv
Date: Sat Mar 19 16:51:45 2016
New Revision: 263888

URL: http://llvm.org/viewvc/llvm-project?rev=263888&view=rev
Log:
[Sema] Make type deduction work with some overloadable functions

Some functions can't have their address taken. If we encounter an
overload set where only one of the candidates can have its address
taken, we should automatically select that candidate's type in type
deduction.

Differential Revision: http://reviews.llvm.org/D15591

Modified:
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/SemaCXX/unaddressable-functions.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=263888&r1=263887&r2=263888&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Sat Mar 19 16:51:45 2016
@@ -3016,6 +3016,11 @@ ResolveOverloadForDeduction(Sema &S, Tem
         return GetTypeOfFunction(S, R, ExplicitSpec);
     }
 
+    DeclAccessPair DAP;
+    if (FunctionDecl *Viable =
+            S.resolveAddressOfOnlyViableOverloadCandidate(Arg, DAP))
+      return GetTypeOfFunction(S, R, Viable);
+
     return QualType();
   }
   

Modified: cfe/trunk/test/SemaCXX/unaddressable-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/unaddressable-functions.cpp?rev=263888&r1=263887&r2=263888&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/unaddressable-functions.cpp (original)
+++ cfe/trunk/test/SemaCXX/unaddressable-functions.cpp Sat Mar 19 16:51:45 2016
@@ -34,3 +34,69 @@ void foo(int) __attribute__((enable_if(f
 
 void *Ptr = reinterpret_cast<void*>(foo); // expected-error{{'foo' is unavailable: don't call this}} expected-note at -3{{explicitly marked unavailable 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 at 53{{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 at -8{{implicitly declared private here}}
+  call(&Foo::staticBar); // expected-error{{'staticBar' is a private member of 'template_deduction::Foo'}} expected-note at -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 at -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>'}}
+}




More information about the cfe-commits mailing list