From d1cc437c65449fb732919bdea73cd6fe53ca9779 Mon Sep 17 00:00:00 2001 From: dgregor Date: Tue, 4 Dec 2007 19:27:14 +0000 Subject: [PATCH] 2007-12-04 Douglas Gregor 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 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 | 10 ++++++++++ gcc/cp/pt.c | 30 +++++++++++++++++++++++++---- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/variadic-unify.C | 15 +++++++++++++++ 4 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-unify.C 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 + + 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 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..38c24c0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-12-04 Douglas Gregor + + PR c++/33091 + * g++.dg/cpp0x/variadic-unify.C: New. + 2007-12-04 Richard Guenther 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 struct tuple { }; + +template +void foo(tuple, tuple, tuple); + +struct X{ }; + +void bar() +{ + tuple tif; + tuple tdx; + tuple tall; + foo(tall, tif, tdx); +} -- 2.7.4