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.
This commit is contained in:
Marek Polacek 2024-09-03 17:01:48 -04:00
parent 9ebc9fbddd
commit 25ac2bb57a
2 changed files with 15 additions and 0 deletions

View File

@ -7951,7 +7951,9 @@ coerce_template_template_parm (tree parm, tree arg, tsubst_flags_t complain,
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 false;

View File

@ -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>();
}