diff options
author | Douglas Gregor <doug.gregor@gmail.com> | 2007-11-10 02:53:31 +0000 |
---|---|---|
committer | Doug Gregor <dgregor@gcc.gnu.org> | 2007-11-10 02:53:31 +0000 |
commit | 49b5e2f6b50347329eaddd44becfec13633f940e (patch) | |
tree | 12a659becde0adb05ab03361808179ad887b8a19 | |
parent | a4d60af8e910e9117536785dc1a9d665b30a665b (diff) | |
download | gcc-49b5e2f6b50347329eaddd44becfec13633f940e.zip gcc-49b5e2f6b50347329eaddd44becfec13633f940e.tar.gz gcc-49b5e2f6b50347329eaddd44becfec13633f940e.tar.bz2 |
re PR c++/33510 (Array size of array with size determined by the initializer wrong with packs)
2007-11-09 Douglas Gregor <doug.gregor@gmail.com>
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 <doug.gregor@gmail.com>
PR c++/33510
* g++.dg/cpp0x/variadic-init.C: New.
From-SVN: r130065
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic-init.C | 56 |
4 files changed, 83 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3a99fba..242f4ae 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2007-11-09 Douglas Gregor <doug.gregor@gmail.com> + + 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 <pinskia@gmail.com> PR c++/30297: diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index ca5a9ca..758d95b 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 40c3dc0..8ca5494 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-11-09 Douglas Gregor <doug.gregor@gmail.com> + + PR c++/33510 + * g++.dg/cpp0x/variadic-init.C: New. + 2007-11-09 Paolo Bonzini <bonzini@gnu.org> Jakub Jelinek <jakub@redhat.com> 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 0000000..34ade85 --- /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<int M, int N> struct pair +{ + int i, j; + pair () : i (M), j (N) {} +}; + +template<int... M> struct S +{ + template<int... N> 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<typename... M> struct R +{ + template<typename... N> 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<char, short, int>::foo<float, double, long> (); +} + + +int main () +{ + int *p = bar (); + if (p[0] != 0 || p[1] != 2 || p[2] != 4 || p[3] != -1) + abort (); +} |