In 61022, we were stripping the pack expansion from a template
argument for considering what kind of argument it is, and then
forgetting to put it back in the case of an unbound class template.

In 72801, we were doing unification wrong when trying to find partial
specialization bindings because we weren't considering template
arguments from an instantiation of the enclosing class template.

Tested x86_64-pc-linux-gnu, applying to trunk and 7.
commit df4a6dd91a46b7b5d2b00cbe2835e509a73257ce
Author: Jason Merrill <ja...@redhat.com>
Date:   Tue Jun 27 18:04:52 2017 -0400

            PR c++/61022 - error with variadic template template parm
    
            * pt.c (convert_template_argument): Keep the TYPE_PACK_EXPANSION.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b86b346..fa75037 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7695,7 +7695,7 @@ convert_template_argument (tree parm,
          if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE)
            /* The number of argument required is not known yet.
               Just accept it for now.  */
-           val = TREE_TYPE (arg);
+           val = orig_arg;
          else
            {
              tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ttp8.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp8.C
new file mode 100644
index 0000000..f3e576a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp8.C
@@ -0,0 +1,27 @@
+// PR c++/69111
+// { dg-do compile { target c++11 } }
+
+template <template <typename> class ...>
+struct template_list {};
+
+template <typename T>
+struct A
+{};
+
+template <typename>
+struct B
+{
+ template <typename T>
+ using type = A<T>;
+};
+
+template <typename ... Types>
+struct C
+{
+ using type = template_list<B<Types>::template type...>;
+};
+
+int main()
+{
+ return 0;
+}
commit 962f55e50dcef0d94db6bab4dbf83f0b4966c6d8
Author: Jason Merrill <ja...@redhat.com>
Date:   Tue Jun 27 16:53:01 2017 -0400

            PR c++/72801 - ICE with variadic partial specialization
    
            * pt.c (unify_pack_expansion): Use PACK_EXPANSION_EXTRA_ARGS.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b060a19..b86b346 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -20044,6 +20044,9 @@ unify_pack_expansion (tree tparms, tree targs, tree 
packed_parms,
   tree pack, packs = NULL_TREE;
   int i, start = TREE_VEC_LENGTH (packed_parms) - 1;
 
+  /* Add in any args remembered from an earlier partial instantiation.  */
+  targs = add_to_template_args (PACK_EXPANSION_EXTRA_ARGS (parm), targs);
+
   packed_args = expand_template_argument_pack (packed_args);
 
   int len = TREE_VEC_LENGTH (packed_args);
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial1.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-partial1.C
new file mode 100644
index 0000000..6f8df3e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial1.C
@@ -0,0 +1,22 @@
+// PR c++/72801
+// { dg-do compile { target c++11 } }
+
+template < typename, typename > struct A {};
+
+template < typename ... T > struct B
+{ 
+  template < typename > struct C
+  { 
+    static const int a = 0;
+  };
+
+  template < typename R, typename ... S >
+  struct C < R (A < T, S > ...) >
+  { 
+    static const int a = 1;
+  };
+};
+
+#define SA(X) static_assert ((X), #X)
+SA(B <>::C<int()>::a == 1);
+

Reply via email to