[PATCH] c++: overload sets and placeholder return type [PR64194]
Patrick Palka
ppalka@redhat.com
Wed Jul 29 19:23:57 GMT 2020
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
>
>
More information about the Gcc-patches
mailing list