This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/83916, C++17 ICE with template template parameters
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 14 Mar 2018 15:15:51 -0400
- Subject: C++ PATCH for c++/83916, C++17 ICE with template template parameters
In the wg21.link/P0522 change to template template parameter matching,
we ran into trouble with this testcase: when we try to form
TTC<TA...>, we need to convert TA to TC, and try to tsubst TC to
produce the real desired type. But trying to look up TC in the args
for TTC fails, and indeed makes no sense. Even if we passed in more
args somehow, what we have in outer_args are args for A, not for C, so
that wouldn't help.
I dealt with this situation by recognizing that we are dealing with
multiple levels of template parms and only have a single level of
template args, so we can't possibly get the right answer, so we
shouldn't do any substitution.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 31437c878831d15bbccbd8a891a074aacfdeec10
Author: Jason Merrill <jason@redhat.com>
Date: Wed Mar 14 11:44:50 2018 -0400
PR c++/83916 - ICE with template template parameters.
* pt.c (convert_template_argument): Don't substitute into type of
non-type parameter if we don't have enough arg levels.
(unify): Likewise.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d720c33cf0a..14321816cde 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7974,7 +7974,11 @@ convert_template_argument (tree parm,
{
tree t = TREE_TYPE (parm);
- if (tree a = type_uses_auto (t))
+ if (TEMPLATE_PARM_LEVEL (get_template_parm_index (parm))
+ > TMPL_ARGS_DEPTH (args))
+ /* We don't have enough levels of args to do any substitution. This
+ can happen in the context of -fnew-ttp-matching. */;
+ else if (tree a = type_uses_auto (t))
{
t = do_auto_deduction (t, arg, a, complain, adc_unify, args);
if (t == error_mark_node)
@@ -21224,14 +21228,22 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
template-parameter exactly, except that a template-argument
deduced from an array bound may be of any integral type.
The non-type parameter might use already deduced type parameters. */
- ++processing_template_decl;
- tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE);
- --processing_template_decl;
- if (tree a = type_uses_auto (tparm))
+ tparm = TREE_TYPE (parm);
+ if (TEMPLATE_PARM_LEVEL (parm) > TMPL_ARGS_DEPTH (targs))
+ /* We don't have enough levels of args to do any substitution. This
+ can happen in the context of -fnew-ttp-matching. */;
+ else
{
- tparm = do_auto_deduction (tparm, arg, a, complain, adc_unify);
- if (tparm == error_mark_node)
- return 1;
+ ++processing_template_decl;
+ tparm = tsubst (tparm, targs, tf_none, NULL_TREE);
+ --processing_template_decl;
+
+ if (tree a = type_uses_auto (tparm))
+ {
+ tparm = do_auto_deduction (tparm, arg, a, complain, adc_unify);
+ if (tparm == error_mark_node)
+ return 1;
+ }
}
if (!TREE_TYPE (arg))
diff --git a/gcc/testsuite/g++.dg/template/ttp31.C b/gcc/testsuite/g++.dg/template/ttp31.C
new file mode 100644
index 00000000000..ff3f1f5c3ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp31.C
@@ -0,0 +1,10 @@
+// PR c++/83916
+// { dg-do compile { target c++11 } }
+
+template<class TA,
+ template<TA...> class TTA, TA... VA>
+struct A { };
+
+template<class UC, class TC,
+ template<TC...> class TTC, TC... VC>
+struct C : A<TC, TTC, VC...> { };
diff --git a/gcc/testsuite/g++.dg/template/ttp32.C b/gcc/testsuite/g++.dg/template/ttp32.C
new file mode 100644
index 00000000000..a96a62d332f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp32.C
@@ -0,0 +1,10 @@
+// PR c++/83916
+// { dg-do compile { target c++17 } }
+
+template<class TA,
+ template<auto...> class TTA, TA... VA>
+struct A { };
+
+template<class UC, class TC,
+ template<auto...> class TTC, TC... VC>
+struct C : A<TC, TTC, VC...> { };