https://gcc.gnu.org/g:25ac2bb57ae400621050a7e0845994336ca83b99

commit r15-3603-g25ac2bb57ae400621050a7e0845994336ca83b99
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.

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 cb3164d49147..769e7999dac1 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -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;
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>();
+}

Reply via email to