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
> 
> 

Reply via email to