[PATCH] c++: Refine check for CTAD placeholder [PR99586]

Jason Merrill jason@redhat.com
Thu Apr 1 17:09:47 GMT 2021


On 4/1/21 10:30 AM, Patrick Palka wrote:
> In the below testcase, during finish_compound_literal for A<B{V}>{},
> type_uses_auto finds and returns the CTAD placeholder for B{V}, which
> tricks us into attempting CTAD on A<B{V}>{} and leads to bogus errors.
> 
> AFAICT 'type' will always be a bare 'auto' in the CTAD case, so we don't
> need to look deeply to find it; checking template_placeholder_p instead
> should suffice here.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, and also on cmcstl2
> and range-v3.  Does this look OK for trunk, or perhaps stage1?

OK for trunk.

> gcc/cp/ChangeLog:
> 
> 	PR c++/99586
> 	* semantics.c (finish_compound_literal): Check
> 	template_placeholder_p instead of type_uses_auto.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c++/99586
> 	* g++.dg/cpp2a/nontype-class42.C: New test.
> ---
>   gcc/cp/semantics.c                           | 15 +++++++--------
>   gcc/testsuite/g++.dg/cpp2a/nontype-class42.C |  8 ++++++++
>   2 files changed, 15 insertions(+), 8 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class42.C
> 
> diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
> index b02596f73bd..8eaaaefe2d6 100644
> --- a/gcc/cp/semantics.c
> +++ b/gcc/cp/semantics.c
> @@ -3036,14 +3036,13 @@ finish_compound_literal (tree type, tree compound_literal,
>         return error_mark_node;
>       }
>   
> -  if (tree anode = type_uses_auto (type))
> -    if (CLASS_PLACEHOLDER_TEMPLATE (anode))
> -      {
> -	type = do_auto_deduction (type, compound_literal, anode, complain,
> -				  adc_variable_type);
> -	if (type == error_mark_node)
> -	  return error_mark_node;
> -      }
> +  if (template_placeholder_p (type))
> +    {
> +      type = do_auto_deduction (type, compound_literal, type, complain,
> +				adc_variable_type);
> +      if (type == error_mark_node)
> +	return error_mark_node;
> +    }
>   
>     /* Used to hold a copy of the compound literal in a template.  */
>     tree orig_cl = NULL_TREE;
> diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class42.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class42.C
> new file mode 100644
> index 00000000000..a688bee6f3d
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class42.C
> @@ -0,0 +1,8 @@
> +// PR c++/99586
> +// { dg-do compile { target c++20 } }
> +
> +template <class T>
> +struct B { constexpr B(T) { } };
> +
> +template <auto> struct A{};
> +template <auto V> auto a = A<B{V}>{};
> 



More information about the Gcc-patches mailing list