[C++ PATCH] PR c++/86986 - ICE with TTP with parameter pack.

Jason Merrill jason@redhat.com
Fri Apr 5 02:49:00 GMT 2019


Three separate issues were breaking this testcase.  One, we were trying to
look at the type of a template template parameter to see if it's a valid
non-type template parameter.  Two, we were treating a parameter pack named
in the type of a template parameter pack of a TTP pack as being one of the
packs expanded by the outer pack.  Three, we weren't supplying all the
necessary levels of template arguments when TTP matching.

Tested x86_64-pc-linux-gnu, applying to trunk.

	* pt.c (coerce_template_parameter_pack): Only look at the type of a
	non-type parameter pack.
	(fixed_parameter_pack_p_1): Don't recurse into the type of a
	non-type parameter pack.
	(coerce_template_template_parms): Call add_outermost_template_args.
---
 gcc/cp/pt.c                                | 14 +++++++++++---
 gcc/testsuite/g++.dg/cpp0x/variadic-ttp9.C | 10 ++++++++++
 gcc/cp/ChangeLog                           |  9 +++++++++
 3 files changed, 30 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-ttp9.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9cb29d22ca3..20647be587a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5116,7 +5116,13 @@ fixed_parameter_pack_p_1 (tree parm, struct find_parameter_pack_data *ppd)
 
   tree vec = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (parm));
   for (int i = 0; i < TREE_VEC_LENGTH (vec); ++i)
-    fixed_parameter_pack_p_1 (TREE_VALUE (TREE_VEC_ELT (vec, i)), ppd);
+    {
+      tree p = TREE_VALUE (TREE_VEC_ELT (vec, i));
+      if (template_parameter_pack_p (p))
+	/* Any packs in the type are expanded by this parameter.  */;
+      else
+	fixed_parameter_pack_p_1 (p, ppd);
+    }
 }
 
 /* PARM is a template parameter pack.  Return any parameter packs used in
@@ -7554,6 +7560,7 @@ coerce_template_template_parms (tree parm_parms,
 	 args and the converted args.  If that succeeds, A is at least as
 	 specialized as P, so they match.*/
       tree pargs = template_parms_level_to_args (parm_parms);
+      pargs = add_outermost_template_args (outer_args, pargs);
       ++processing_template_decl;
       pargs = coerce_template_parms (arg_parms, pargs, NULL_TREE, tf_none,
 				     /*require_all*/true, /*use_default*/true);
@@ -8184,8 +8191,9 @@ coerce_template_parameter_pack (tree parms,
           int j, len = TREE_VEC_LENGTH (packed_parms);
           for (j = 0; j < len; ++j)
             {
-              tree t = TREE_TYPE (TREE_VEC_ELT (packed_parms, j));
-              if (invalid_nontype_parm_type_p (t, complain))
+              tree t = TREE_VEC_ELT (packed_parms, j);
+              if (TREE_CODE (t) == PARM_DECL
+		  && invalid_nontype_parm_type_p (TREE_TYPE (t), complain))
                 return error_mark_node;
             }
 	  /* We don't know how many args we have yet, just
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ttp9.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp9.C
new file mode 100644
index 00000000000..63e3f2684aa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp9.C
@@ -0,0 +1,10 @@
+// PR c++/86986
+// { dg-do compile { target c++11 } }
+
+template<class... T>
+struct X {
+    template<template<T...> class...>
+    struct Y { };
+};
+
+using type = X<int>::Y<>;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 729b7732565..55a083fab6f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2019-04-04  Jason Merrill  <jason@redhat.com>
+
+	PR c++/86986 - ICE with TTP with parameter pack.
+	* pt.c (coerce_template_parameter_pack): Only look at the type of a
+	non-type parameter pack.
+	(fixed_parameter_pack_p_1): Don't recurse into the type of a
+	non-type parameter pack.
+	(coerce_template_template_parms): Call add_outermost_template_args.
+
 2019-04-04  Martin Sebor  <msebor@redhat.com>
 
 	PR c++/89974

base-commit: 7395ef5fd901285c705689bbfa3da70c70a5b237
-- 
2.20.1



More information about the Gcc-patches mailing list