diff options
author | Patrick Palka <ppalka@redhat.com> | 2023-07-26 17:21:26 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2023-07-26 17:21:26 -0400 |
commit | b3adcc60dcf3314f47f5409aecef40607f82b80b (patch) | |
tree | 5e657441ad4de0ed09da06f7067d2e032d4f6ef9 /gcc | |
parent | 74290c664d1d4c067a996253fe505555ec671668 (diff) | |
download | gcc-b3adcc60dcf3314f47f5409aecef40607f82b80b.zip gcc-b3adcc60dcf3314f47f5409aecef40607f82b80b.tar.gz gcc-b3adcc60dcf3314f47f5409aecef40607f82b80b.tar.bz2 |
c++: passing partially inst tmpl as ttp [PR110566]
Since the template arguments 'pargs' we pass to 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 rather than 2, and the arguments are {{int}, {N, M}},
which results in a crash during auto deduction for parameters' types.
PR c++/110566
PR c++/108179
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/pt.cc | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ttp38.C | 12 |
2 files changed, 17 insertions, 7 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 43818ba..210d622 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 0000000..4a0c27f --- /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<auto X, auto Y> struct C; +}; + +using type = A<B<int>::C>; |