On Wed, 29 Jul 2020, Patrick Palka wrote: > In the testcase below, template argument deduction for the call > g(id<int>) goes wrong because the functions in the overload set id<int> > each have a yet-undeduced auto return type, and this undeduced return > type makes try_one_overload fail to match up any of these functions with > g's parameter type, leading to g's template parameter going undeduced > and to the overload set going unresolved. > > This patch fixes this issue by performing return type deduction via > instantiation before doing try_one_overload, in a manner similar to what > resolve_address_of_overloaded_function does. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to > commit? > > gcc/cp/ChangeLog: > > PR c++/64194 > * pt.c (resolve_overloaded_unification): If the function > template specialization has a placeholder return type, > then instantiate it before attempting unification. > > gcc/testsuite/ChangeLog: > > PR c++/64194 > * g++.dg/cpp1y/auto-fn60.C: New test. > --- > gcc/cp/pt.c | 11 ++++++++++- > gcc/testsuite/g++.dg/cpp1y/auto-fn60.C | 11 +++++++++++ > 2 files changed, 21 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1y/auto-fn60.C > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index 4d955c555dc..abb74520fc9 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -22118,7 +22118,16 @@ resolve_overloaded_unification (tree tparms, > if (subargs != error_mark_node > && !any_dependent_template_arguments_p (subargs)) > { > - elem = TREE_TYPE (instantiate_template (fn, subargs, tf_none)); > + fn = instantiate_template (fn, subargs, tf_none); > + if (undeduced_auto_decl (fn)) > + { > + /* Instantiate the function to deduce its return type. */ > + ++function_depth; > + instantiate_decl (fn, /*defer*/false, /*class*/false); > + --function_depth; > + } > + > + elem = TREE_TYPE (fn); > if (try_one_overload (tparms, targs, tempargs, parm, > elem, strict, sub_strict, addr_p, explain_p) > && (!goodfn || !same_type_p (goodfn, elem))) > diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn60.C > b/gcc/testsuite/g++.dg/cpp1y/auto-fn60.C > new file mode 100644 > index 00000000000..237868c076b > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn60.C > @@ -0,0 +1,11 @@ > +// PR c++/64194 > +// { dg-do compile { target c++14 } } > + > +template <typename T> void g(void (*)(T)) { } > + > +template <typename T> auto id(int) { } > +template <typename T> auto id(char) { return 0; } > + > +int main() { > + g(id<void>);
Oops, this is supposed to use id<int> instead of id<void> to match up with the commit message (or vice versa). > +} > -- > 2.28.0.rc1 > >