In resolve_address_of_overloaded_function, currently only the second pass over the overload set (which considers just the function templates in the overload set) checks constraints and performs return type deduction when necessary. But as the testcases below show, we need to do this when considering non-template functions during the first pass, too.
Tested on x86_64-pc-linux-gnu, does this look OK for trunk? gcc/cp/ChangeLog: PR c++/96647 * class.c (resolve_address_of_overloaded_function): Also check constraints and perform return type deduction when considering non-template functions in the overload set. gcc/testsuite/ChangeLog: PR c++/96647 * g++.dg/cpp0x/auto-96647.C: New test. * g++.dg/cpp2a/concepts-fn6.C: New test. --- gcc/cp/class.c | 16 ++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/auto-96647.C | 10 ++++++++++ gcc/testsuite/g++.dg/cpp2a/concepts-fn6.C | 10 ++++++++++ 3 files changed, 36 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/auto-96647.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-fn6.C diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 3479b8207d2..c15cb04c654 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -8286,6 +8286,22 @@ resolve_address_of_overloaded_function (tree target_type, one, or vice versa. */ continue; + /* Constraints must be satisfied. This is done before + return type deduction since that instantiates the + function. */ + if (!constraints_satisfied_p (fn)) + continue; + + if (undeduced_auto_decl (fn)) + { + /* Force instantiation to do return type deduction. */ + ++function_depth; + instantiate_decl (fn, /*defer*/false, /*class*/false); + --function_depth; + + require_deduced_type (fn); + } + /* In C++17 we need the noexcept-qualifier to compare types. */ if (flag_noexcept_type && !maybe_instantiate_noexcept (fn, complain)) diff --git a/gcc/testsuite/g++.dg/cpp0x/auto-96647.C b/gcc/testsuite/g++.dg/cpp0x/auto-96647.C new file mode 100644 index 00000000000..314b2a16ac2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto-96647.C @@ -0,0 +1,10 @@ +// PR c++/96647 +// { dg-do compile { target c++11 } } + +template<typename> +struct Base { + auto f(int) { } + auto f(char) { } +}; + +void (Base<void>::*ptr)(int) = &Base<void>::f; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-fn6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-fn6.C new file mode 100644 index 00000000000..3d7941658d4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn6.C @@ -0,0 +1,10 @@ +// PR c++/96647 +// { dg-do compile { target c++20 } } + +template<typename T> +struct Base { + auto f(int) { } + auto f(int) requires T::fail { static_assert(T::fail); } +}; + +void (Base<void>::*ptr)(int) = &Base<void>::f; -- 2.28.0.358.g20de7e7e4f