diff mbox series

[C++] Make taking the address of an overloaded function a non-deduced context

Message ID CAFk2RUZ+yx4ftYzL5g36B90-k_4tG2ahqKJ5ZC9ouxteLkvtEQ@mail.gmail.com
State New
Headers show
Series [C++] Make taking the address of an overloaded function a non-deduced context | expand

Commit Message

Ville Voutilainen Aug. 29, 2017, 10:19 p.m. UTC
2017-08-29  Ville Voutilainen  <ville.voutilainen@gmail.com>

    Make taking the address of an overloaded function a non-deduced context

    cp/

    * pt.c (unify_overload_resolution_failure): Return unify_success
    instead of unify_invalid.

    testsuite/

    * g++.dg/overload/template6.C: New.

Comments

Ville Voutilainen Aug. 29, 2017, 10:25 p.m. UTC | #1
On 30 August 2017 at 01:19, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> 2017-08-29  Ville Voutilainen  <ville.voutilainen@gmail.com>
>
>     Make taking the address of an overloaded function a non-deduced context
>
>     cp/
>
>     * pt.c (unify_overload_resolution_failure): Return unify_success
>     instead of unify_invalid.
>
>     testsuite/
>
>     * g++.dg/overload/template6.C: New.

Ah yes, tested on Linux-PPC64. I see some libstdc++ (runtime) failures
from the testsuite, but as far as I can
see they are there even before this patch.
Ville Voutilainen Aug. 30, 2017, 12:19 p.m. UTC | #2
On 30 August 2017 at 01:25, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> On 30 August 2017 at 01:19, Ville Voutilainen
> <ville.voutilainen@gmail.com> wrote:
>> 2017-08-29  Ville Voutilainen  <ville.voutilainen@gmail.com>
>>
>>     Make taking the address of an overloaded function a non-deduced context
>>
>>     cp/
>>
>>     * pt.c (unify_overload_resolution_failure): Return unify_success
>>     instead of unify_invalid.
>>
>>     testsuite/
>>
>>     * g++.dg/overload/template6.C: New.
>
> Ah yes, tested on Linux-PPC64. I see some libstdc++ (runtime) failures
> from the testsuite, but as far as I can
> see they are there even before this patch.

..and were caused by an unclean libstdc++ build on my end. The patch
passes the full testsuite with
no regressions.
Jason Merrill Aug. 30, 2017, 4:07 p.m. UTC | #3
On Tue, Aug 29, 2017 at 6:19 PM, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> 2017-08-29  Ville Voutilainen  <ville.voutilainen@gmail.com>
>
>     Make taking the address of an overloaded function a non-deduced context
>
>     cp/
>
>     * pt.c (unify_overload_resolution_failure): Return unify_success
>     instead of unify_invalid.

Please also remove the error.  OK with that change.

Jason
Ville Voutilainen Aug. 30, 2017, 5:08 p.m. UTC | #4
On 30 August 2017 at 19:07, Jason Merrill <jason@redhat.com> wrote:
> Please also remove the error.  OK with that change.


Here's a new and much improved version as discussed on IRC. Tested on
Linux-PPC64.
Ok for trunk?

2017-08-30  Ville Voutilainen  <ville.voutilainen@gmail.com>

    Make taking the address of an overloaded function a non-deduced context

    cp/

    * pt.c (unify_overload_resolution_failure): Remove.
    (unify_one_argument): Adjust.

    testsuite/

    * g++.dg/overload/template6.C: New.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 564ffb0..5cfe292 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6363,16 +6363,6 @@ unify_template_argument_mismatch (bool explain_p, tree parm, tree arg)
   return unify_invalid (explain_p);
 }
 
-static int
-unify_overload_resolution_failure (bool explain_p, tree arg)
-{
-  if (explain_p)
-    inform (input_location,
-	    "  could not resolve address from overloaded function %qE",
-	    arg);
-  return unify_invalid (explain_p);
-}
-
 /* Attempt to convert the non-type template parameter EXPR to the
    indicated TYPE.  If the conversion is successful, return the
    converted value.  If the conversion is unsuccessful, return
@@ -19090,12 +19080,10 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
 		 templates and at most one of a set of
 		 overloaded functions provides a unique
 		 match.  */
-
-	      if (resolve_overloaded_unification
-		  (tparms, targs, parm, arg, strict,
-		   arg_strict, explain_p))
-		return unify_success (explain_p);
-	      return unify_overload_resolution_failure (explain_p, arg);
+	      resolve_overloaded_unification (tparms, targs, parm,
+					      arg, strict,
+					      arg_strict, explain_p);
+	      return unify_success (explain_p);
 	    }
 
 	  arg_expr = arg;
diff --git a/gcc/testsuite/g++.dg/overload/template6.C b/gcc/testsuite/g++.dg/overload/template6.C
new file mode 100644
index 0000000..f2650aa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/template6.C
@@ -0,0 +1,47 @@
+// { dg-do compile { target c++11 } }
+
+template <typename>
+struct is_function {
+  static constexpr bool value = false;
+};
+
+template <typename R, typename ...Args>
+struct is_function<R(Args...)>
+{
+  static constexpr bool value = true;
+};
+
+template<bool, typename> struct enable_if {};
+
+template<typename T> struct enable_if<true, T> 
+{
+  typedef T type;
+};
+
+template <class T>
+struct remove_pointer
+{
+  typedef T type;
+};
+
+template <class T>
+struct remove_pointer<T*>
+{
+  typedef T type;
+};
+
+void f(int) {}
+void f(double) {}
+
+template <class T>
+struct X
+{
+  template <class U=T,
+	    typename enable_if<is_function<
+				 typename remove_pointer<U>::type>::value,
+			       bool>::type = false> X(U&&) {}
+};
+
+int main() {
+  X<void(*)(int)> x0(f);
+}
Jason Merrill Aug. 30, 2017, 8:41 p.m. UTC | #5
On Wed, Aug 30, 2017 at 1:08 PM, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> On 30 August 2017 at 19:07, Jason Merrill <jason@redhat.com> wrote:
>> Please also remove the error.  OK with that change.
>
> Here's a new and much improved version as discussed on IRC. Tested on
> Linux-PPC64.
> Ok for trunk?
>
> 2017-08-30  Ville Voutilainen  <ville.voutilainen@gmail.com>
>
>     Make taking the address of an overloaded function a non-deduced context
>
>     cp/
>
>     * pt.c (unify_overload_resolution_failure): Remove.
>     (unify_one_argument): Adjust.

Please add a comment before unify_success along the lines of "If there
isn't a unique match, this is a non-deduced context, so we still
succeed."  OK with that change.

Jason
diff mbox series

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 564ffb0..4f731fd 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6370,7 +6370,7 @@  unify_overload_resolution_failure (bool explain_p, tree arg)
     inform (input_location,
 	    "  could not resolve address from overloaded function %qE",
 	    arg);
-  return unify_invalid (explain_p);
+  return unify_success (explain_p);
 }
 
 /* Attempt to convert the non-type template parameter EXPR to the
diff --git a/gcc/testsuite/g++.dg/overload/template6.C b/gcc/testsuite/g++.dg/overload/template6.C
new file mode 100644
index 0000000..f2650aa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/template6.C
@@ -0,0 +1,47 @@ 
+// { dg-do compile { target c++11 } }
+
+template <typename>
+struct is_function {
+  static constexpr bool value = false;
+};
+
+template <typename R, typename ...Args>
+struct is_function<R(Args...)>
+{
+  static constexpr bool value = true;
+};
+
+template<bool, typename> struct enable_if {};
+
+template<typename T> struct enable_if<true, T> 
+{
+  typedef T type;
+};
+
+template <class T>
+struct remove_pointer
+{
+  typedef T type;
+};
+
+template <class T>
+struct remove_pointer<T*>
+{
+  typedef T type;
+};
+
+void f(int) {}
+void f(double) {}
+
+template <class T>
+struct X
+{
+  template <class U=T,
+	    typename enable_if<is_function<
+				 typename remove_pointer<U>::type>::value,
+			       bool>::type = false> X(U&&) {}
+};
+
+int main() {
+  X<void(*)(int)> x0(f);
+}