OSDN Git Service

PR middle-end/19687
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 30 Jan 2005 02:13:46 +0000 (02:13 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 30 Jan 2005 02:13:46 +0000 (02:13 +0000)
        * expr.c (categorize_ctor_elements_1): Check for CONSTRUCTOR of a
        union being empty.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94421 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/gcc.c-torture/execute/pr19687.c [new file with mode: 0644]

index fa4fd37..f3bcde3 100644 (file)
@@ -1,5 +1,11 @@
 2005-01-29  Richard Henderson  <rth@redhat.com>
 
+       PR middle-end/19687
+       * expr.c (categorize_ctor_elements_1): Check for CONSTRUCTOR of a
+       union being empty.
+
+2005-01-29  Richard Henderson  <rth@redhat.com>
+
        * combine.c (make_field_assignment): Fix argument order
        to gen_int_mode.
 
index 1f82b1d..29acbba 100644 (file)
@@ -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 (file)
index 0000000..c300ab4
--- /dev/null
@@ -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;
+}