2007-12-04 Douglas Gregor <doug.gregor@gmail.com>
authordgregor <dgregor@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 4 Dec 2007 19:27:14 +0000 (19:27 +0000)
committerdgregor <dgregor@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 4 Dec 2007 19:27:14 +0000 (19:27 +0000)
       PR c++/33091
       * pt.c (unify_pack_expansion): If we didn't deduce any actual
       bindings for the template parameter pack, don't try to keep the
       empty deduced arguments.
       (unify): If a parameter is a template-id whose template argument
       list contains a pack expansion that is not at the end, then we
       cannot unify against that template-id.

2007-12-04  Douglas Gregor  <doug.gregor@gmail.com>

       PR c++/33091
       * g++.dg/cpp0x/variadic-unify.C: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130604 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 097f8fa..9b99ba8 100644 (file)
@@ -1,3 +1,13 @@
+2007-12-04  Douglas Gregor  <doug.gregor@gmail.com>
+
+       PR c++/33091
+       * pt.c (unify_pack_expansion): If we didn't deduce any actual
+       bindings for the template parameter pack, don't try to keep the
+       empty deduced arguments.
+       (unify): If a parameter is a template-id whose template argument
+       list contains a pack expansion that is not at the end, then we
+       cannot unify against that template-id.
+
 2007-12-02  Paolo Carlini  <pcarlini@suse.de>
 
         PR c++/34061
index f70147d..f7d6946 100644 (file)
@@ -12464,6 +12464,16 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
     {
       tree old_pack = TREE_VALUE (pack);
       tree new_args = TREE_TYPE (pack);
+      int i, len = TREE_VEC_LENGTH (new_args);
+      bool nondeduced_p = false;
+
+      /* If NEW_ARGS contains any NULL_TREE entries, we didn't
+        actually deduce anything.  */
+      for (i = 0; i < len && !nondeduced_p; ++i)
+       if (TREE_VEC_ELT (new_args, i) == NULL_TREE)
+         nondeduced_p = true;
+      if (nondeduced_p)
+       continue;
 
       if (old_pack && ARGUMENT_PACK_INCOMPLETE_P (old_pack))
         {
@@ -13156,10 +13166,22 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
         int argslen = TREE_VEC_LENGTH (packed_args);
         int parm_variadic_p = 0;
 
-        /* Check if the parameters end in a pack, making them variadic.  */
-        if (len > 0 
-           && PACK_EXPANSION_P (TREE_VEC_ELT (packed_parms, len - 1)))
-          parm_variadic_p = 1;
+       for (i = 0; i < len; ++i)
+         {
+           if (PACK_EXPANSION_P (TREE_VEC_ELT (packed_parms, i)))
+             {
+               if (i == len - 1)
+                 /* We can unify against something with a trailing
+                    parameter pack.  */
+                 parm_variadic_p = 1;
+               else
+                 /* Since there is something following the pack
+                    expansion, we cannot unify this template argument
+                    list.  */
+                 return 0;
+             }
+         }
+         
 
         /* If we don't have enough arguments to satisfy the parameters
            (not counting the pack expression at the end), or we have
index 920ffa3..38c24c0 100644 (file)
@@ -1,3 +1,8 @@
+2007-12-04  Douglas Gregor  <doug.gregor@gmail.com>
+
+       PR c++/33091
+       * g++.dg/cpp0x/variadic-unify.C: New.
+
 2007-12-04  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/34334
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-unify.C b/gcc/testsuite/g++.dg/cpp0x/variadic-unify.C
new file mode 100644 (file)
index 0000000..5423439
--- /dev/null
@@ -0,0 +1,15 @@
+// { dg-options "-std=c++0x" }
+template<typename...> struct tuple { };
+
+template<typename... Args1, typename... Args2>
+void foo(tuple<Args1..., Args2...>, tuple<Args1...>, tuple<Args2...>);
+
+struct X{ };
+
+void bar()
+{
+  tuple<int, float> tif;
+  tuple<double, X> tdx;
+  tuple<int, float, double, X> tall;
+  foo(tall, tif, tdx);
+}