On Wed, Jul 19, 2023 at 2:05 PM Patrick Palka <ppa...@redhat.com> wrote:
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk/13?
>
> -- >8 --
>
> Since the arguments 'pargs' passed to the coerce_template_parms from
> coerce_template_template_parms are always a full set, we need to make sure
> we always pass the parameters of the most general template because if the
> template is partially instantiated then the levels won't match up.  In the
> testcase below during said call to coerce_template_parms the parameters
> are {X, Y} both level 1, but the arguments are {{int}, {N, M}}, which
> leads to a crash during auto deduction of X and Y.
>
>         PR c++/110566
>
> gcc/cp/ChangeLog:
>
>         * pt.cc (coerce_template_template_parms): Simplify by using
>         DECL_INNERMOST_TEMPLATE_PARMS and removing redundant asserts.
>         Always pass the parameters of the most general template to
>         coerce_template_parms.
>
> gcc/testsuite/ChangeLog:
>
>         * g++.dg/template/ttp38.C: New test.
> ---
>  gcc/cp/pt.cc                          | 12 +++++-------
>  gcc/testsuite/g++.dg/template/ttp38.C | 12 ++++++++++++
>  2 files changed, 17 insertions(+), 7 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/template/ttp38.C
>
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index d882e9dd117..8723868823e 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -8073,12 +8073,10 @@ coerce_template_template_parms (tree parm_tmpl,
>    tree parm, arg;
>    int variadic_p = 0;
>
> -  tree parm_parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS 
> (parm_tmpl));
> -  tree arg_parms_full = DECL_TEMPLATE_PARMS (arg_tmpl);
> -  tree arg_parms = INNERMOST_TEMPLATE_PARMS (arg_parms_full);
> -
> -  gcc_assert (TREE_CODE (parm_parms) == TREE_VEC);
> -  gcc_assert (TREE_CODE (arg_parms) == TREE_VEC);
> +  tree parm_parms = DECL_INNERMOST_TEMPLATE_PARMS (parm_tmpl);
> +  tree arg_parms = DECL_INNERMOST_TEMPLATE_PARMS (arg_tmpl);
> +  tree gen_arg_tmpl = most_general_template (arg_tmpl);
> +  tree gen_arg_parms = DECL_INNERMOST_TEMPLATE_PARMS (gen_arg_tmpl);
>
>    nparms = TREE_VEC_LENGTH (parm_parms);
>    nargs = TREE_VEC_LENGTH (arg_parms);
> @@ -8134,7 +8132,7 @@ coerce_template_template_parms (tree parm_tmpl,
>         scope_args = TI_ARGS (tinfo);
>        pargs = add_to_template_args (scope_args, pargs);
>
> -      pargs = coerce_template_parms (arg_parms, pargs, NULL_TREE, tf_none);
> +      pargs = coerce_template_parms (gen_arg_parms, pargs, NULL_TREE, 
> tf_none);
>        if (pargs != error_mark_node)
>         {
>           tree targs = make_tree_vec (nargs);
> diff --git a/gcc/testsuite/g++.dg/template/ttp38.C 
> b/gcc/testsuite/g++.dg/template/ttp38.C
> new file mode 100644
> index 00000000000..7d25d291e81
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/template/ttp38.C
> @@ -0,0 +1,12 @@
> +// PR c++/110566
> +// { dg-do compile { target c++20 } }
> +
> +template<template<int N, int M> class>
> +struct A;
> +
> +template<class T>
> +struct B {
> +  template<int X, int Y> struct C;

Oops, I botched a git commit --amend.  The parameter list here should
be 'auto X, auto Y'.

> +};
> +
> +using type = A<B<int>::C>;
> --
> 2.41.0.376.gcba07a324d
>

Reply via email to