fix middle-end/19687
Richard Henderson
rth@redhat.com
Sun Jan 30 02:16:00 GMT 2005
After seeing Alan Modra post an incorrect patch for this problem,
I was spurred to make this an execute test to validate correctness.
Tested on i386-linux.
r~
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.776
diff -u -p -r1.776 expr.c
--- expr.c 27 Jan 2005 00:07:41 -0000 1.776
+++ expr.c 30 Jan 2005 02:13:20 -0000
@@ -4364,29 +4364,33 @@ categorize_ctor_elements_1 (tree ctor, H
|| 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)
- {
- /* 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;
+ if (list)
+ {
+ /* 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;
Index: testsuite/gcc.c-torture/execute/pr19687.c
===================================================================
RCS file: testsuite/gcc.c-torture/execute/pr19687.c
diff -N testsuite/gcc.c-torture/execute/pr19687.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.c-torture/execute/pr19687.c 30 Jan 2005 02:13:20 -0000
@@ -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;
+}
More information about the Gcc-patches
mailing list