From: dgregor Date: Sat, 10 Nov 2007 02:53:31 +0000 (+0000) Subject: 2007-11-09 Douglas Gregor X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=08d094fee3d5209bceafe4c34a727a8ed84781f3;p=thirdparty%2Fgcc.git 2007-11-09 Douglas Gregor PR c++/33510 * decl.c (cp_complete_array_type): If any of the initializer elements are pack expansions, don't compute the array size yet. 2007-11-09 Douglas Gregor PR c++/33510 * g++.dg/cpp0x/variadic-init.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130065 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3a99fbaadacc..242f4aec4fd6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2007-11-09 Douglas Gregor + + PR c++/33510 + * decl.c (cp_complete_array_type): If any of the initializer + elements are pack expansions, don't compute the array size yet. + 2007-11-08 Andrew Pinski PR c++/30297: diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index ca5a9ca2483a..758d95b05bbf 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4331,7 +4331,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init) HOST_WIDE_INT i; for (i = 0; VEC_iterate (constructor_elt, v, i, ce); - ++i) + ++i) if (!check_array_designated_initializer (ce)) failure = 1; } @@ -6110,6 +6110,9 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) if (initial_value) { + unsigned HOST_WIDE_INT i; + tree value; + /* An array of character type can be initialized from a brace-enclosed string constant. @@ -6126,6 +6129,18 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) && VEC_length (constructor_elt, v) == 1) initial_value = value; } + + /* If any of the elements are parameter packs, we can't actually + complete this type now because the array size is dependent. */ + if (TREE_CODE (initial_value) == CONSTRUCTOR) + { + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (initial_value), + i, value) + { + if (PACK_EXPANSION_P (value)) + return 0; + } + } } failure = complete_array_type (ptype, initial_value, do_default); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 40c3dc07528e..8ca5494d2f66 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-11-09 Douglas Gregor + + PR c++/33510 + * g++.dg/cpp0x/variadic-init.C: New. + 2007-11-09 Paolo Bonzini Jakub Jelinek diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-init.C b/gcc/testsuite/g++.dg/cpp0x/variadic-init.C new file mode 100644 index 000000000000..34ade85e0f99 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-init.C @@ -0,0 +1,56 @@ +// { dg-do run } +// { dg-options "-std=gnu++0x" } + +// PR c++/33510 +#define SIZE_FROM_CTOR +extern "C" void abort (); + +template struct pair +{ + int i, j; + pair () : i (M), j (N) {} +}; + +template struct S +{ + template static int *foo () + { +#ifdef SIZE_FROM_CTOR + static int x[] = { (M + N)..., -1 }; +#else + static int x[1 + sizeof... N] = { (M + N)..., -1 }; +#endif + return x; + } +}; + +template struct R +{ + template static int *foo () + { +#ifdef SIZE_FROM_CTOR + static int x[] = { (sizeof(M) + sizeof(N))..., -1 }; +#else + static int x[1 + sizeof... N] = { (sizeof(M) + sizeof(N))..., -1 }; +#endif + return x; + } +}; + +int *bar () +{ + return S<0, 1, 2>::foo<0, 1, 2> (); +} + +int *baz () +{ + return R::foo (); +} + + +int main () +{ + int *p = bar (); + if (p[0] != 0 || p[1] != 2 || p[2] != 4 || p[3] != -1) + abort (); +}