2017-08-29 Ville Voutilainen <[email protected]>
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);
+}