From patchwork Tue Jul 27 22:05:46 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: C++0x PATCH for a couple of variadic templates/value-initialization issues Date: Tue, 27 Jul 2010 12:05:46 -0000 From: Jason Merrill X-Patchwork-Id: 60051 Message-Id: <4C4F583A.4040703@redhat.com> To: gcc-patches List Cc: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= Daniel pointed out a couple of bugs with our handling of value-initialization when a pack expansion expands to 0 elements. In one, we were failing to give an error message for value-initializing an array of unknown bound; in the other we were passing an AGGR_INIT_EXPR into cp_finish_decl, which isn't prepared to handle it. Tested x86_64-pc-linux-gnu, applied to trunk. commit 8807d220e86960d8ede6faabd963307c5951c278 Author: Jason Merrill Date: Tue Jul 27 11:03:35 2010 -0400 * pt.c (tsubst_expr) [DECL_EXPR]: Handle getting an AGGR_INIT_EXPR from build_value_init. * init.c (build_value_init_noctor): Give error for unknown array bound. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index d796fd0..0edb800 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -379,7 +379,10 @@ build_value_init_noctor (tree type) /* If we have an error_mark here, we should just return error mark as we don't know the size of the array yet. */ if (max_index == error_mark_node) - return error_mark_node; + { + error ("cannot value-initialize array of unknown bound %qT", type); + return error_mark_node; + } gcc_assert (TREE_CODE (max_index) == INTEGER_CST); /* A zero-sized array, which is accepted as an extension, will diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7a33147..2777ab7 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11697,14 +11697,18 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, tree t = RECUR (init); if (init && !t) - /* If we had an initializer but it - instantiated to nothing, - value-initialize the object. This will - only occur when the initializer was a - pack expansion where the parameter packs - used in that expansion were of length - zero. */ - init = build_value_init (TREE_TYPE (decl)); + { + /* If we had an initializer but it + instantiated to nothing, + value-initialize the object. This will + only occur when the initializer was a + pack expansion where the parameter packs + used in that expansion were of length + zero. */ + init = build_value_init (TREE_TYPE (decl)); + if (TREE_CODE (init) == AGGR_INIT_EXPR) + init = get_target_expr (init); + } else init = t; } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic102.C b/gcc/testsuite/g++.dg/cpp0x/variadic102.C new file mode 100644 index 0000000..dc9c4ae --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic102.C @@ -0,0 +1,19 @@ +// { dg-options "-std=c++0x" } + +struct nAny { + template + nAny(T&&...); +}; + +template +T&& create(); + +template +void test() { + T t(create()...); + (void) t; +} + +int main() { + test(); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic103.C b/gcc/testsuite/g++.dg/cpp0x/variadic103.C new file mode 100644 index 0000000..6d12331 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic103.C @@ -0,0 +1,14 @@ +// { dg-options "-std=c++0x" } + +template +T&& create(); + +template +void test() { + T t(create()...); // { dg-error "unknown bound" } + (void) t; +} + +int main() { + test(); +}