[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