Make taking the address of an overloaded function a non-deduced context
authorVille Voutilainen <ville.voutilainen@gmail.com>
Wed, 30 Aug 2017 20:50:25 +0000 (23:50 +0300)
committerVille Voutilainen <ville@gcc.gnu.org>
Wed, 30 Aug 2017 20:50:25 +0000 (23:50 +0300)
cp/

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

testsuite/

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

From-SVN: r251548

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/overload/template6.C [new file with mode: 0644]

index 69267c0ec35147c04011fc1f59469d69ad7fa1c9..10ae08ae18693965c93f982338e3c5a43d0c65a8 100644 (file)
@@ -1,3 +1,10 @@
+2017-08-30  Ville Voutilainen  <ville.voutilainen@gmail.com>
+
+       Make taking the address of an overloaded function a non-deduced context
+
+       * pt.c (unify_overload_resolution_failure): Remove.
+       (unify_one_argument): Adjust.
+
 2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 141b4d7564a8de9d1a2c0041cdfbce5ea5bda404..f4868abfda2623837542a8765265402c443e0acf 100644 (file)
@@ -6400,16 +6400,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
@@ -19305,12 +19295,12 @@ 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);
+             /* If a unique match was not found, this is a
+                non-deduced context, so we still succeed. */
+             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 (file)
index 0000000..f2650aa
--- /dev/null
@@ -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);
+}