https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991

--- Comment #28 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Trying:
--- gcc/stor-layout.c.jj        2018-02-22 14:35:33.135216198 +0100
+++ gcc/stor-layout.c   2018-02-27 17:32:17.934820133 +0100
@@ -1038,7 +1038,7 @@ update_alignment_for_field (record_layou
         the type, except that for zero-size bitfields this only
         applies if there was an immediately prior, nonzero-size
         bitfield.  (That's the way it is, experimentally.) */
-      if ((!is_bitfield && !DECL_PACKED (field))
+      if (!is_bitfield
          || ((DECL_SIZE (field) == NULL_TREE
               || !integer_zerop (DECL_SIZE (field)))
              ? !DECL_PACKED (field)
@@ -1047,7 +1047,10 @@ update_alignment_for_field (record_layou
                 && ! integer_zerop (DECL_SIZE (rli->prev_field)))))
        {
          unsigned int type_align = TYPE_ALIGN (type);
-         type_align = MAX (type_align, desired_align);
+         if (!is_bitfield && DECL_PACKED (field))
+           type_align = desired_align;
+         else
+           type_align = MAX (type_align, desired_align);
          if (maximum_field_alignment != 0)
            type_align = MIN (type_align, maximum_field_alignment);
          rli->record_align = MAX (rli->record_align, type_align);
@@ -1303,7 +1306,9 @@ place_field (record_layout_info rli, tre

   /* Does this field automatically have alignment it needs by virtue
      of the fields that precede it and the record's own alignment?  */
-  if (known_align < desired_align)
+  if (known_align < desired_align
+      && (! targetm.ms_bitfield_layout_p (rli->t)
+         || rli->prev_field == NULL))
     {
       /* No, we need to skip space before this field.
         Bump the cumulative size to multiple of field alignment.  */
@@ -1331,8 +1336,6 @@ place_field (record_layout_info rli, tre

       if (! TREE_CONSTANT (rli->offset))
        rli->offset_align = desired_align;
-      if (targetm.ms_bitfield_layout_p (rli->t))
-       rli->prev_field = NULL;
     }

   /* Handle compatibility with PCC.  Note that if the record has any
@@ -1505,6 +1508,31 @@ place_field (record_layout_info rli, tre
                   as if the prior field was not a bitfield.  */
                prev_saved = NULL;

+             /* Does this field automatically have alignment it needs by
virtue
+                of the fields that precede it and the record's own alignment? 
*/
+             if (known_align < desired_align)
+               {
+                 /* If the alignment is still within offset_align, just align
+                    the bit position.  */
+                 if (desired_align < rli->offset_align)
+                   rli->bitpos = round_up (rli->bitpos, desired_align);
+                 else
+                   {
+                     /* First adjust OFFSET by the partial bits, then align. 
*/
+                     tree d = size_binop (CEIL_DIV_EXPR, rli->bitpos,
+                                          bitsize_unit_node);
+                     rli->offset = size_binop (PLUS_EXPR, rli->offset,
+                                               fold_convert (sizetype, d));
+                     rli->bitpos = bitsize_zero_node;
+
+                     rli->offset = round_up (rli->offset,
+                                             desired_align / BITS_PER_UNIT);
+                   }
+
+                 if (! TREE_CONSTANT (rli->offset))
+                   rli->offset_align = desired_align;
+               }
+
              /* Cause a new bitfield to be captured, either this time (if
                 currently a bitfield) or next time we see one.  */
              if (!DECL_BIT_FIELD_TYPE (field)
@@ -1530,7 +1558,7 @@ place_field (record_layout_info rli, tre
       if (!DECL_BIT_FIELD_TYPE (field)
          || (prev_saved != NULL
              ? !simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type))
-             : !integer_zerop (DECL_SIZE (field)) ))
+             : !integer_zerop (DECL_SIZE (field))))
        {
          /* Never smaller than a byte for compatibility.  */
          unsigned int type_align = BITS_PER_UNIT;
@@ -1555,7 +1583,8 @@ place_field (record_layout_info rli, tre
            }

          /* Now align (conventionally) for the new type.  */
-         type_align = TYPE_ALIGN (TREE_TYPE (field));
+         if (! DECL_PACKED (field))
+           type_align = TYPE_ALIGN (TREE_TYPE (field));

          if (maximum_field_alignment != 0)
            type_align = MIN (type_align, maximum_field_alignment);

fixes this testcase, but breaks bf-ms-layout.c and bf-ms-layout-2.c.
The tests were adjusted in r186880 and r184519, but perhaps those were just
bogus changes.  I guess what matters more is whether the layout in those tests
and in the above tests match what VC does.

Reply via email to