[PATCH] c++: template-id ADL and partial instantiation [PR99911]

Jason Merrill jason@redhat.com
Thu Nov 18 05:15:42 GMT 2021


On 11/10/21 11:53, Patrick Palka wrote:
> Here when partially instantiating the call get<U>(T{}) with T=N::A
> (for which earlier unqualified name lookup for 'get' found nothing)
> the arguments after substitution are no longer dependent but the callee
> still is, so perform_koenig_lookup postpones ADL.  But then we go on to
> diagnose the unresolved template name anyway, as if ADL was already
> performed and failed.
> 
> This patch fixes this by avoiding the error path in question when the
> template arguments of an unresolved template-id are dependent, which
> mirrors the dependence check in perform_koenig_lookup.

This change is OK.

> In passing, this
> patch also disables the -fpermissive fallback that performs a second
> unqualified lookup in the template-id ADL case; this fallback seems to be
> intended for legacy code and shouldn't be used for C++20 template-id ADL.

Why wouldn't we want the more helpful diagnostic?

> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk and perhaps 11?
> 
> 	PR c++/99911
> 
> gcc/cp/ChangeLog:
> 
> 	* pt.c (tsubst_copy_and_build) <case CALL_EXPR>: Don't diagnose
> 	name lookup failure if the arguments to an unresolved template
> 	name are still dependent.  Disable the -fpermissive fallback for
> 	template-id ADL.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/cpp2a/fn-template24.C: New test.
> ---
>   gcc/cp/pt.c                                |  6 ++++--
>   gcc/testsuite/g++.dg/cpp2a/fn-template24.C | 16 ++++++++++++++++
>   2 files changed, 20 insertions(+), 2 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/fn-template24.C
> 
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index 991a20a85d4..4beddf9caf8 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -20427,12 +20427,14 @@ tsubst_copy_and_build (tree t,
>   	if (function != NULL_TREE
>   	    && (identifier_p (function)
>   		|| (TREE_CODE (function) == TEMPLATE_ID_EXPR
> -		    && identifier_p (TREE_OPERAND (function, 0))))
> +		    && identifier_p (TREE_OPERAND (function, 0))
> +		    && !any_dependent_template_arguments_p (TREE_OPERAND
> +							    (function, 1))))
>   	    && !any_type_dependent_arguments_p (call_args))
>   	  {
>   	    if (TREE_CODE (function) == TEMPLATE_ID_EXPR)
>   	      function = TREE_OPERAND (function, 0);
> -	    if (koenig_p && (complain & tf_warning_or_error))
> +	    else if (koenig_p && (complain & tf_warning_or_error))
>   	      {
>   		/* For backwards compatibility and good diagnostics, try
>   		   the unqualified lookup again if we aren't in SFINAE
> diff --git a/gcc/testsuite/g++.dg/cpp2a/fn-template24.C b/gcc/testsuite/g++.dg/cpp2a/fn-template24.C
> new file mode 100644
> index 00000000000..b444ac6a273
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/fn-template24.C
> @@ -0,0 +1,16 @@
> +// PR c++/99911
> +// { dg-do compile { target c++20 } }
> +
> +namespace N {
> +  struct A { };
> +  template<class T> void get(A);
> +};
> +
> +template<class T>
> +auto f() {
> +  return []<class U>(U) { get<U>(T{}); };
> +}
> +
> +int main() {
> +  f<N::A>()(0);
> +}
> 



More information about the Gcc-patches mailing list