https://gcc.gnu.org/g:4088319e7ce98f813988a36f98a18ee30ff7f1d8
commit r14-10668-g4088319e7ce98f813988a36f98a18ee30ff7f1d8 Author: Marek Polacek <pola...@redhat.com> Date: Tue Sep 3 17:01:48 2024 -0400 c++: ICE with TTP [PR96097] We crash when dependent_type_p gets a TEMPLATE_TYPE_PARM outside a template. That happens here because in template <template <typename T, typename T::type TT> typename X> void func() {} template <typename U, int I> struct Y {}; void g() { func<Y>(); } when performing overload resolution for func<Y>() we have to check if U matches T and I matches TT. So we wind up in coerce_template_template_parm/PARM_DECL. TREE_TYPE (arg) is int so we try to substitute TT's type, which is T::type. But we have nothing to substitute T with. And we call make_typename_type where ctx is still T, which checks dependent_scope_p and we trip the assert. It should work to always perform the substitution in a template context. If the result still contains template parameters, we cannot say if they match. PR c++/96097 gcc/cp/ChangeLog: * pt.cc (coerce_template_template_parm): Increment processing_template_decl before calling tsubst. gcc/testsuite/ChangeLog: * g++.dg/template/ttp44.C: New test. (cherry picked from commit 25ac2bb57ae400621050a7e0845994336ca83b99) Diff: --- gcc/cp/pt.cc | 2 ++ gcc/testsuite/g++.dg/template/ttp44.C | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 6695e4ff49f0..85228b9f9435 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -7933,7 +7933,9 @@ coerce_template_template_parm (tree parm, i.e. the parameter list of TT depends on earlier parameters. */ if (!uses_template_parms (TREE_TYPE (arg))) { + ++processing_template_decl; tree t = tsubst (TREE_TYPE (parm), outer_args, complain, in_decl); + --processing_template_decl; if (!uses_template_parms (t) && !same_type_p (t, TREE_TYPE (arg))) return 0; diff --git a/gcc/testsuite/g++.dg/template/ttp44.C b/gcc/testsuite/g++.dg/template/ttp44.C new file mode 100644 index 000000000000..2a4129752433 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp44.C @@ -0,0 +1,13 @@ +// PR c++/96097 +// { dg-do compile } + +template <template <typename T, typename T::type TT> class X> +void func() {} + +template <typename U, int I> +struct Y {}; + +void test() +{ + func<Y>(); +}