Re: [PATCH] D15591: [Bugfix] Make type deduction work more nicely with unaddressable functions

2016-03-19 Thread George Burgess IV via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL263888: [Sema] Make type deduction work with some 
overloadable functions (authored by gbiv).

Changed prior to commit:
  http://reviews.llvm.org/D15591?vs=49337=51120#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D15591

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

Index: cfe/trunk/test/SemaCXX/unaddressable-functions.cpp
===
--- cfe/trunk/test/SemaCXX/unaddressable-functions.cpp
+++ cfe/trunk/test/SemaCXX/unaddressable-functions.cpp
@@ -34,3 +34,69 @@
 
 void *Ptr = reinterpret_cast(foo); // expected-error{{'foo' is 
unavailable: don't call this}} expected-note@-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  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@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 ''}}
+}
+
+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(::bar, Foo()); // expected-error{{'bar' is a private member of 
'template_deduction::Foo'}} expected-note@-8{{implicitly declared private here}}
+  call(::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();
+auto Fail = call(); // expected-error{{no matching function for call to 
'call'}} expected-note@-5{{candidate template ignored: couldn't infer template 
argument 'Fn'}}
+
+auto PtrOk = ;
+auto PtrFail =  // expected-error{{variable 'PtrFail' with type 'auto' 
has incompatible initializer of type ''}}
+}
Index: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
===
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
@@ -3016,6 +3016,11 @@
 return GetTypeOfFunction(S, R, ExplicitSpec);
 }
 
+DeclAccessPair DAP;
+if (FunctionDecl *Viable =
+S.resolveAddressOfOnlyViableOverloadCandidate(Arg, DAP))
+  return GetTypeOfFunction(S, R, Viable);
+
 return QualType();
   }
   


Index: cfe/trunk/test/SemaCXX/unaddressable-functions.cpp
===
--- cfe/trunk/test/SemaCXX/unaddressable-functions.cpp
+++ cfe/trunk/test/SemaCXX/unaddressable-functions.cpp
@@ -34,3 +34,69 @@
 
 void *Ptr = reinterpret_cast(foo); // expected-error{{'foo' is unavailable: don't call this}} expected-note@-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  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'}} 

Re: [PATCH] D15591: [Bugfix] Make type deduction work more nicely with unaddressable functions

2016-03-19 Thread Richard Smith via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

LGTM


http://reviews.llvm.org/D15591



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D15591: [Bugfix] Make type deduction work more nicely with unaddressable functions

2016-02-28 Thread George Burgess IV via cfe-commits
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(::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(::bar, Foo()); // expected-error{{'bar' is a private member of 
'template_deduction::Foo'}} expected-note@-8{{implicitly declared private here}}
+  call(::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();
+auto Fail = call(); // expected-error{{no matching function for call to 
'call'}} expected-note@-5{{candidate template ignored: couldn't infer template 
argument 'Fn'}}
+
+auto PtrOk = ;
+auto PtrFail =  // expected-error{{variable 'PtrFail' with type 'auto' 
has incompatible initializer of 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(::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