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); +}