re PR middle-end/28160 (Bogus "size of array 'foo' is too large" error with -mms...
authorKaz Kojima <kkojima@gcc.gnu.org>
Sat, 15 Jul 2006 06:58:57 +0000 (06:58 +0000)
committerKaz Kojima <kkojima@gcc.gnu.org>
Sat, 15 Jul 2006 06:58:57 +0000 (06:58 +0000)
PR middle-end/28160
* stor-layout.c (place_field): Take the bit field with
an excessive size into account in the ms-bitfiled case.

PR middle-end/28161
* stor-layout.c (place_field): Use DECL_BIT_FIELD_TYPE of
the previous bit field.

From-SVN: r115464

gcc/ChangeLog
gcc/stor-layout.c

index c2abdff..8bdcd70 100644 (file)
@@ -1,3 +1,13 @@
+2006-07-15  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       PR middle-end/28160
+       * stor-layout.c (place_field): Take the bit field with
+       an excessive size into account in the ms-bitfiled case.
+
+       PR middle-end/28161
+       * stor-layout.c (place_field): Use DECL_BIT_FIELD_TYPE of
+       the previous bit field.
+
 2006-07-14  Eliot Dresselhaus  <eliot@sonic.net>
 
        PR target/27287
index 76aa4ac..415f7c1 100644 (file)
@@ -1022,6 +1022,7 @@ place_field (record_layout_info rli, tree field)
   if (targetm.ms_bitfield_layout_p (rli->t))
     {
       tree prev_saved = rli->prev_field;
+      tree prev_type = prev_saved ? DECL_BIT_FIELD_TYPE (prev_saved) : NULL;
 
       /* This is a bitfield if it exists.  */
       if (rli->prev_field)
@@ -1037,8 +1038,7 @@ place_field (record_layout_info rli, tree field)
              && !integer_zerop (DECL_SIZE (rli->prev_field))
              && host_integerp (DECL_SIZE (rli->prev_field), 0)
              && host_integerp (TYPE_SIZE (type), 0)
-             && simple_cst_equal (TYPE_SIZE (type),
-                                  TYPE_SIZE (TREE_TYPE (rli->prev_field))))
+             && simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type)))
            {
              /* We're in the middle of a run of equal type size fields; make
                 sure we realign if we run out of bits.  (Not decl size,
@@ -1047,17 +1047,20 @@ place_field (record_layout_info rli, tree field)
 
              if (rli->remaining_in_alignment < bitsize)
                {
+                 HOST_WIDE_INT typesize = tree_low_cst (TYPE_SIZE (type), 1);
+
                  /* out of bits; bump up to next 'word'.  */
-                 rli->offset = DECL_FIELD_OFFSET (rli->prev_field);
                  rli->bitpos
-                   = size_binop (PLUS_EXPR, TYPE_SIZE (type),
-                                 DECL_FIELD_BIT_OFFSET (rli->prev_field));
+                   = size_binop (PLUS_EXPR, rli->bitpos,
+                                 bitsize_int (rli->remaining_in_alignment));
                  rli->prev_field = field;
-                 rli->remaining_in_alignment
-                   = tree_low_cst (TYPE_SIZE (type), 1);
+                 if (typesize < bitsize)
+                   rli->remaining_in_alignment = 0;
+                 else
+                   rli->remaining_in_alignment = typesize - bitsize;
                }
-
-             rli->remaining_in_alignment -= bitsize;
+             else
+               rli->remaining_in_alignment -= bitsize;
            }
          else
            {
@@ -1105,8 +1108,7 @@ place_field (record_layout_info rli, tree field)
 
       if (!DECL_BIT_FIELD_TYPE (field)
          || (prev_saved != NULL
-             ? !simple_cst_equal (TYPE_SIZE (type),
-                                  TYPE_SIZE (TREE_TYPE (prev_saved)))
+             ? !simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type))
              : !integer_zerop (DECL_SIZE (field)) ))
        {
          /* Never smaller than a byte for compatibility.  */
@@ -1119,9 +1121,16 @@ place_field (record_layout_info rli, tree field)
          if (DECL_SIZE (field) != NULL
              && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 0)
              && host_integerp (DECL_SIZE (field), 0))
-           rli->remaining_in_alignment
-             = tree_low_cst (TYPE_SIZE (TREE_TYPE(field)), 1)
-               - tree_low_cst (DECL_SIZE (field), 1);
+           {
+             HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 1);
+             HOST_WIDE_INT typesize
+               = tree_low_cst (TYPE_SIZE (TREE_TYPE (field)), 1);
+
+             if (typesize < bitsize)
+               rli->remaining_in_alignment = 0;
+             else
+               rli->remaining_in_alignment = typesize - bitsize;
+           }
 
          /* Now align (conventionally) for the new type.  */
          type_align = TYPE_ALIGN (TREE_TYPE (field));