PR c++/81215 - deduction failure with variadic TTP.
authorJason Merrill <jason@redhat.com>
Mon, 26 Jun 2017 18:49:18 +0000 (14:49 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 26 Jun 2017 18:49:18 +0000 (14:49 -0400)
* pt.c (unify_bound_ttp_args): Restore old logic for C++14 and down.

From-SVN: r249664

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/variadic-ttp7.C [new file with mode: 0644]

index 8bc268c1dcd4af9300aba7e7f4342a6f6f1b735a..c067d23eb8a2f14a62d6f82cf71fc370db24956f 100644 (file)
@@ -1,3 +1,8 @@
+2017-06-26  Jason Merrill  <jason@redhat.com>
+
+       PR c++/81215 - deduction failure with variadic TTP.
+       * pt.c (unify_bound_ttp_args): Restore old logic for C++14 and down.
+
 2017-06-26  Martin Sebor  <msebor@redhat.com>
 
        PR c++/81169
index 392fba07714b30b17a5ba41cd7719b06628fdf34..43f9ca8b39e6b9ab4aab69bf27e3028814c78370 100644 (file)
@@ -7170,26 +7170,68 @@ unify_bound_ttp_args (tree tparms, tree targs, tree parm, tree& arg,
   parmvec = expand_template_argument_pack (parmvec);
   argvec = expand_template_argument_pack (argvec);
 
-  tree nparmvec = parmvec;
   if (flag_new_ttp)
     {
       /* In keeping with P0522R0, adjust P's template arguments
         to apply to A's template; then flatten it again.  */
+      tree nparmvec = parmvec;
       nparmvec = coerce_ttp_args_for_tta (arg, parmvec, tf_none);
       nparmvec = expand_template_argument_pack (nparmvec);
-    }
 
-  if (unify (tparms, targs, nparmvec, argvec,
-            UNIFY_ALLOW_NONE, explain_p))
-    return 1;
+      if (unify (tparms, targs, nparmvec, argvec,
+                UNIFY_ALLOW_NONE, explain_p))
+       return 1;
 
-  /* If the P0522 adjustment eliminated a pack expansion, deduce
-     empty packs.  */
-  if (flag_new_ttp
-      && TREE_VEC_LENGTH (nparmvec) < TREE_VEC_LENGTH (parmvec)
-      && unify_pack_expansion (tparms, targs, parmvec, argvec,
-                              DEDUCE_EXACT, /*sub*/true, explain_p))
-    return 1;
+      /* If the P0522 adjustment eliminated a pack expansion, deduce
+        empty packs.  */
+      if (flag_new_ttp
+         && TREE_VEC_LENGTH (nparmvec) < TREE_VEC_LENGTH (parmvec)
+         && unify_pack_expansion (tparms, targs, parmvec, argvec,
+                                  DEDUCE_EXACT, /*sub*/true, explain_p))
+       return 1;
+    }
+  else
+    {
+      /* Deduce arguments T, i from TT<T> or TT<i>.
+        We check each element of PARMVEC and ARGVEC individually
+        rather than the whole TREE_VEC since they can have
+        different number of elements, which is allowed under N2555.  */
+
+      int len = TREE_VEC_LENGTH (parmvec);
+
+      /* Check if the parameters end in a pack, making them
+        variadic.  */
+      int parm_variadic_p = 0;
+      if (len > 0
+         && PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, len - 1)))
+       parm_variadic_p = 1;
+
+      for (int i = 0; i < len - parm_variadic_p; ++i)
+       /* If the template argument list of P contains a pack
+          expansion that is not the last template argument, the
+          entire template argument list is a non-deduced
+          context.  */
+       if (PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, i)))
+         return unify_success (explain_p);
+
+      if (TREE_VEC_LENGTH (argvec) < len - parm_variadic_p)
+       return unify_too_few_arguments (explain_p,
+                                       TREE_VEC_LENGTH (argvec), len);
+
+      for (int i = 0; i < len - parm_variadic_p; ++i)
+       if (unify (tparms, targs,
+                  TREE_VEC_ELT (parmvec, i),
+                  TREE_VEC_ELT (argvec, i),
+                  UNIFY_ALLOW_NONE, explain_p))
+         return 1;
+
+      if (parm_variadic_p
+         && unify_pack_expansion (tparms, targs,
+                                  parmvec, argvec,
+                                  DEDUCE_EXACT,
+                                  /*subr=*/true, explain_p))
+       return 1;
+    }
 
   return 0;
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ttp7.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp7.C
new file mode 100644 (file)
index 0000000..0dbe904
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/81215
+// { dg-do compile { target c++11 } }
+
+template<typename U> struct X { };
+template<typename T, typename U = void> struct set { };
+
+template <typename V, template <typename...> class C>
+void bar (const X<C<V>>&)
+{
+}
+
+void
+foo (X<set<int>>& x)
+{
+  bar (x);
+}