From 486e432615e3a3e526044f3002db03a0ddbc04b5 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 29 Jan 2005 18:13:46 -0800 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 +++ gcc/expr.c | 42 ++++++++++--------- gcc/testsuite/gcc.c-torture/execute/pr19687.c | 18 ++++++++ 3 files changed, 47 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr19687.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fa4fd37d8ca..f3bcde399f8 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 1f82b1d9834..29acbba5c5b 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 00000000000..c300ab48cf0 --- /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; +} -- 2.30.2