diff options
author | Marek Polacek <polacek@redhat.com> | 2024-09-03 17:01:48 -0400 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2024-09-12 09:14:48 -0400 |
commit | 25ac2bb57ae400621050a7e0845994336ca83b99 (patch) | |
tree | 5f8163c3ff9b8fa140d1738dbd9212eaab599b5d | |
parent | 9ebc9fbdddfe1ec85355b068354315a4da8e1ca0 (diff) | |
download | gcc-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.cc | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ttp44.C | 13 |
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>(); +} |