On 30 August 2017 at 19:07, Jason Merrill <ja...@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.voutilai...@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);
+}

Reply via email to