aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2024-09-03 17:01:48 -0400
committerMarek Polacek <polacek@redhat.com>2024-09-12 09:14:48 -0400
commit25ac2bb57ae400621050a7e0845994336ca83b99 (patch)
tree5f8163c3ff9b8fa140d1738dbd9212eaab599b5d
parent9ebc9fbdddfe1ec85355b068354315a4da8e1ca0 (diff)
downloadgcc-25ac2bb57ae400621050a7e0845994336ca83b99.zip
gcc-25ac2bb57ae400621050a7e0845994336ca83b99.tar.gz
gcc-25ac2bb57ae400621050a7e0845994336ca83b99.tar.bz2
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.
-rw-r--r--gcc/cp/pt.cc2
-rw-r--r--gcc/testsuite/g++.dg/template/ttp44.C13
2 files changed, 15 insertions, 0 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index cb3164d..769e799 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 0000000..2a41297
--- /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>();
+}