diff options
author | Douglas Gregor <doug.gregor@gmail.com> | 2007-12-04 19:27:14 +0000 |
---|---|---|
committer | Doug Gregor <dgregor@gcc.gnu.org> | 2007-12-04 19:27:14 +0000 |
commit | db60ff18e2cc35235d436c7e492d8564af44ea9b (patch) | |
tree | c478f5de91e148280be2fea7572e582a5530a765 /gcc | |
parent | 54b7b17d73286a19d9a8f218f6ecf4d75e680046 (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/pt.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic-unify.C | 15 |
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); +} |