2017-08-29  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): Return unify_success
    instead of unify_invalid.

    testsuite/

    * g++.dg/overload/template6.C: New.
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);
+}

Reply via email to