From: Richard Henderson Date: Sun, 30 Jan 2005 02:13:46 +0000 (-0800) Subject: re PR middle-end/19687 (ICE with union initializer) X-Git-Tag: releases/gcc-4.0.0~1190 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=486e432615e3a3e526044f3002db03a0ddbc04b5;p=thirdparty%2Fgcc.git re PR middle-end/19687 (ICE with union initializer) PR middle-end/19687 * expr.c (categorize_ctor_elements_1): Check for CONSTRUCTOR of a union being empty. From-SVN: r94421 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fa4fd37d8ca4..f3bcde399f8a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-01-29 Richard Henderson + + PR middle-end/19687 + * expr.c (categorize_ctor_elements_1): Check for CONSTRUCTOR of a + union being empty. + 2005-01-29 Richard Henderson * combine.c (make_field_assignment): Fix argument order diff --git a/gcc/expr.c b/gcc/expr.c index 1f82b1d98346..29acbba5c5bb 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4364,29 +4364,33 @@ categorize_ctor_elements_1 (tree ctor, HOST_WIDE_INT *p_nz_elts, || TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE)) { tree init_sub_type; + bool clear_this = true; - /* We don't expect more than one element of the union to be - initialized. Not sure what we should do otherwise... */ list = CONSTRUCTOR_ELTS (ctor); - gcc_assert (TREE_CHAIN (list) == NULL); - - init_sub_type = TREE_TYPE (TREE_VALUE (list)); - - /* ??? We could look at each element of the union, and find the - largest element. Which would avoid comparing the size of the - initialized element against any tail padding in the union. - Doesn't seem worth the effort... */ - if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)), - TYPE_SIZE (init_sub_type)) == 1) + if (list) { - /* And now we have to find out if the element itself is fully - constructed. E.g. for union { struct { int a, b; } s; } u - = { .s = { .a = 1 } }. */ - if (elt_count != count_type_elements (init_sub_type)) - *p_must_clear = true; + /* We don't expect more than one element of the union to be + initialized. Not sure what we should do otherwise... */ + gcc_assert (TREE_CHAIN (list) == NULL); + + init_sub_type = TREE_TYPE (TREE_VALUE (list)); + + /* ??? We could look at each element of the union, and find the + largest element. Which would avoid comparing the size of the + initialized element against any tail padding in the union. + Doesn't seem worth the effort... */ + if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)), + TYPE_SIZE (init_sub_type)) == 1) + { + /* And now we have to find out if the element itself is fully + constructed. E.g. for union { struct { int a, b; } s; } u + = { .s = { .a = 1 } }. */ + if (elt_count == count_type_elements (init_sub_type)) + clear_this = false; + } } - else - *p_must_clear = true; + + *p_must_clear = clear_this; } *p_nz_elts += nz_elts; diff --git a/gcc/testsuite/gcc.c-torture/execute/pr19687.c b/gcc/testsuite/gcc.c-torture/execute/pr19687.c new file mode 100644 index 000000000000..c300ab48cf05 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr19687.c @@ -0,0 +1,18 @@ +extern void abort (void); + +union U +{ + int i, j[4]; +}; + +int main () +{ + union U t = {}; + int i; + + for (i = 0; i < 4; ++i) + if (t.j[i] != 0) + abort (); + + return 0; +}