OSDN Git Service

* gcc.dg/ppc64-toc.c: Don't explicitly use -m64.
[pf3gnuchains/gcc-fork.git] / gcc / expr.c
index 1f82b1d..ab7cf93 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;
@@ -5222,12 +5226,18 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
         the field we're storing into, that mask is redundant.  This is
         particularly common with bit field assignments generated by the
         C front end.  */
-      if (TREE_CODE (exp) == NOP_EXPR
-         && INTEGRAL_TYPE_P (TREE_TYPE (exp))
-         && (TYPE_PRECISION (TREE_TYPE (exp))
-             < GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp))))
-         && bitsize == TYPE_PRECISION (TREE_TYPE (exp)))
-       exp = TREE_OPERAND (exp, 0);
+      if (TREE_CODE (exp) == NOP_EXPR)
+       {
+         tree type = TREE_TYPE (exp);
+         if (INTEGRAL_TYPE_P (type)
+             && TYPE_PRECISION (type) < GET_MODE_BITSIZE (TYPE_MODE (type))
+             && bitsize == TYPE_PRECISION (type))
+           {
+             type = TREE_TYPE (TREE_OPERAND (exp, 0));
+             if (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) >= bitsize)
+               exp = TREE_OPERAND (exp, 0);
+           }
+       }
 
       temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);