From: Jason Merrill Date: Sat, 3 Jan 2009 00:19:55 +0000 (-0500) Subject: re PR c++/38698 (ICE initializing union with initializer list) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fc94bfc598fd5e0aacc9add9cfea4e521d329e97;p=gcc.git re PR c++/38698 (ICE initializing union with initializer list) PR c++/38698 * typeck2.c (process_init_constructor_union): Handle excess initializers. (process_init_constructor_record): Likewise. PR c++/38684 * typeck2.c (digest_init_r): Don't use process_init_constructor for non-aggregate classes. From-SVN: r143024 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e6cb2891a6e..7ffa760679b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2009-01-02 Jason Merrill + + PR c++/38698 + * typeck2.c (process_init_constructor_union): Handle excess + initializers. + (process_init_constructor_record): Likewise. + + PR c++/38684 + * typeck2.c (digest_init_r): Don't use process_init_constructor + for non-aggregate classes. + 2008-12-31 Jakub Jelinek PR c++/38647 diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 207dd9917d9..e313e4b9a5d 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -820,7 +820,8 @@ digest_init_r (tree type, tree init, bool nested) || TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == COMPLEX_TYPE); - if (BRACE_ENCLOSED_INITIALIZER_P (init)) + if (BRACE_ENCLOSED_INITIALIZER_P (init) + && !TYPE_NON_AGGREGATE_CLASS (type)) return process_init_constructor (type, init); else { @@ -1081,6 +1082,9 @@ process_init_constructor_record (tree type, tree init) CONSTRUCTOR_APPEND_ELT (v, field, next); } + if (idx < VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init))) + error ("too many initializers for %qT", type); + CONSTRUCTOR_ELTS (init) = v; return flags; } @@ -1093,12 +1097,19 @@ static int process_init_constructor_union (tree type, tree init) { constructor_elt *ce; + int len; /* If the initializer was empty, use default zero initialization. */ if (VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (init))) return 0; - gcc_assert (VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)) == 1); + len = VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)); + if (len > 1) + { + error ("too many initializers for %qT", type); + VEC_block_remove (constructor_elt, CONSTRUCTOR_ELTS (init), 1, len-1); + } + ce = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (init), 0); /* If this element specifies a field, initialize via that field. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9b59cb4cf3d..199784f5269 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-01-02 Jason Merrill + + * g++.dg/cpp0x/initlist11.C: New test. + * g++.dg/cpp0x/initlist12.C: New test. + 2009-01-02 Richard Sandiford * gcc.dg/fixed-point/composite-type.c: Update wording of messages. diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist11.C b/gcc/testsuite/g++.dg/cpp0x/initlist11.C new file mode 100644 index 00000000000..789afc07556 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist11.C @@ -0,0 +1,17 @@ +// PR c++/38684 + +#include + +struct Y {}; + +struct X : Y { + X(std::initializer_list) {} +}; + +struct A { + X v; +}; + +int main() { + A a{ {1,2,3} }; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist12.C b/gcc/testsuite/g++.dg/cpp0x/initlist12.C new file mode 100644 index 00000000000..f3329d9b63e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist12.C @@ -0,0 +1,15 @@ +// PR c++/38698 + +struct A +{ + int i; +}; + +A a({1,2}); + +union U +{ + int i,j; +}; + +U u({1,2});