aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDouglas Gregor <doug.gregor@gmail.com>2007-12-04 19:27:14 +0000
committerDoug Gregor <dgregor@gcc.gnu.org>2007-12-04 19:27:14 +0000
commitdb60ff18e2cc35235d436c7e492d8564af44ea9b (patch)
treec478f5de91e148280be2fea7572e582a5530a765 /gcc
parent54b7b17d73286a19d9a8f218f6ecf4d75e680046 (diff)
downloadgcc-db60ff18e2cc35235d436c7e492d8564af44ea9b.zip
gcc-db60ff18e2cc35235d436c7e492d8564af44ea9b.tar.gz
gcc-db60ff18e2cc35235d436c7e492d8564af44ea9b.tar.bz2
re PR c++/33091 ([c++0x] ICE using remove_reference on variadic param pack)
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-04 Douglas Gregor <doug.gregor@gmail.com> PR c++/33091 * g++.dg/cpp0x/variadic-unify.C: New. From-SVN: r130604
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/pt.c30
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-unify.C15
4 files changed, 56 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 097f8fa..9b99ba8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f70147d..f7d6946 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 920ffa3..38c24c0c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..5423439
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-unify.C
@@ -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);
+}