]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/52991 (attribute packed broken on mingw32?)
authorJakub Jelinek <jakub@redhat.com>
Wed, 28 Feb 2018 17:17:29 +0000 (18:17 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 28 Feb 2018 17:17:29 +0000 (18:17 +0100)
PR target/52991
* stor-layout.c (update_alignment_for_field): For
targetm.ms_bitfield_layout_p (rli->t), if !is_bitfield
&& !DECL_PACKED (field), do the alignment update, just use
only desired_align instead of MAX (type_align, desired_align)
as the alignment.
(place_field): Don't do known_align < desired_align handling
early if targetm.ms_bitfield_layout_p (rli->t) and rli->prev_field
is non-NULL, instead do it after rli->prev_field handling and
only if not within a bitfield word.  For DECL_PACKED (field)
use type_align of BITS_PER_UNIT.

* gcc.dg/bf-ms-layout.c: Revert 2012-04-26 changes.
* gcc.dg/bf-ms-layout-2.c: Revert 2012-02-23 changes.
* gcc.dg/bf-ms-layout-4.c: New test.
* gcc.dg/bf-ms-layout-5.c: New test.

From-SVN: r258075

gcc/ChangeLog
gcc/stor-layout.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/bf-ms-layout-2.c
gcc/testsuite/gcc.dg/bf-ms-layout-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/bf-ms-layout-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/bf-ms-layout.c

index aece6243bf3877ba9d1b3533415a372aa03ff831..5d3319c00f0071c27ee84c38743c6e0e34806553 100644 (file)
@@ -1,3 +1,17 @@
+2018-02-28  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/52991
+       * stor-layout.c (update_alignment_for_field): For
+       targetm.ms_bitfield_layout_p (rli->t), if !is_bitfield
+       && !DECL_PACKED (field), do the alignment update, just use
+       only desired_align instead of MAX (type_align, desired_align)
+       as the alignment.
+       (place_field): Don't do known_align < desired_align handling
+       early if targetm.ms_bitfield_layout_p (rli->t) and rli->prev_field
+       is non-NULL, instead do it after rli->prev_field handling and
+       only if not within a bitfield word.  For DECL_PACKED (field)
+       use type_align of BITS_PER_UNIT.
+
 2018-02-28  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config/aarch64/aarch64.c (aarch64_emit_probe_stack_range): Remove
index a4eeff18ec0db855b569505b9096858cbe211d41..81f75a5eb72b22b5e77e0affb804e6c820fe69ca 100644 (file)
@@ -1038,7 +1038,7 @@ update_alignment_for_field (record_layout_info rli, tree field,
         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_layout_info rli, tree field,
                 && ! 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, tree field)
 
   /* 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, tree field)
 
       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
@@ -1448,6 +1451,8 @@ place_field (record_layout_info rli, tree field)
       /* This is a bitfield if it exists.  */
       if (rli->prev_field)
        {
+         bool realign_p = known_align < desired_align;
+
          /* If both are bitfields, nonzero, and the same size, this is
             the middle of a run.  Zero declared size fields are special
             and handled as "end of run". (Note: it's nonzero declared
@@ -1481,7 +1486,10 @@ place_field (record_layout_info rli, tree field)
                    rli->remaining_in_alignment = typesize - bitsize;
                }
              else
-               rli->remaining_in_alignment -= bitsize;
+               {
+                 rli->remaining_in_alignment -= bitsize;
+                 realign_p = false;
+               }
            }
          else
            {
@@ -1512,6 +1520,31 @@ place_field (record_layout_info rli, tree field)
                rli->prev_field = NULL;
            }
 
+         /* Does this field automatically have alignment it needs by virtue
+            of the fields that precede it and the record's own alignment?  */
+         if (realign_p)
+           {
+             /* 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;
+           }
+
          normalize_rli (rli);
         }
 
@@ -1530,7 +1563,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 (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 +1588,8 @@ place_field (record_layout_info rli, tree field)
            }
 
          /* 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);
index 14b666d5df964bbbc7e68d922aabfa84e762414e..090d55bf9cfb7df9eb5db032e9d0ec488ba37b08 100644 (file)
@@ -1,3 +1,11 @@
+2018-02-28  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/52991
+       * gcc.dg/bf-ms-layout.c: Revert 2012-04-26 changes.
+       * gcc.dg/bf-ms-layout-2.c: Revert 2012-02-23 changes.
+       * gcc.dg/bf-ms-layout-4.c: New test.
+       * gcc.dg/bf-ms-layout-5.c: New test.
+
 2018-02-28  Peter Bergner  <bergner@vnet.ibm.com>
 
        PR target/83399
index 2d0215fbd52402d38b2c7922e812c49d104703ec..519785a82352a8254b434861520db6ed48ee16e0 100644 (file)
@@ -158,27 +158,27 @@ int main(){
   struct ten test_ten;
 
 #if defined (_TEST_MS_LAYOUT) || defined (_MSC_VER)
-  size_t exp_sizeof_one = 8;
-  size_t exp_sizeof_two = 12;
+  size_t exp_sizeof_one = 12;
+  size_t exp_sizeof_two = 16;
   size_t exp_sizeof_three =6;
   size_t exp_sizeof_four = 8;
   size_t exp_sizeof_five = 3;
   size_t exp_sizeof_six = 8;
   size_t exp_sizeof_seven = 3;
-  size_t exp_sizeof_eight = 2;
+  size_t exp_sizeof_eight = 4;
   size_t exp_sizeof_nine = 8;
-  size_t exp_sizeof_ten = 8;
+  size_t exp_sizeof_ten = 16;
 
-  unsigned char exp_one_c = 7;
-  unsigned char exp_two_c  = 9;
+  unsigned char exp_one_c = 8;
+  unsigned char exp_two_c  = 12;
   unsigned char exp_three_c = 4;
   unsigned char exp_four_c = 4;
   char exp_five_c = 2;
   char exp_six_c = 5;
   char exp_seven_c = 2;
-  char exp_eight_c = 1;
+  char exp_eight_c = 2;
   char exp_nine_c = 0;
-  char exp_ten_c = 1;
+  char exp_ten_c = 8;
 
 #else /* testing -mno-ms-bitfields */
 
diff --git a/gcc/testsuite/gcc.dg/bf-ms-layout-4.c b/gcc/testsuite/gcc.dg/bf-ms-layout-4.c
new file mode 100644 (file)
index 0000000..821db07
--- /dev/null
@@ -0,0 +1,43 @@
+/* PR target/52991 */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+
+#define CHECK(expr) extern char c[(expr) ? 1 : -1]
+#define offsetof(x, y) __builtin_offsetof (x, y)
+
+struct test_sp1 {
+    int a;
+    short b;
+    int c;
+    char d;
+} __attribute__((packed,ms_struct));
+
+CHECK (sizeof (struct test_sp1) == 11);
+CHECK (offsetof (struct test_sp1, a) == 0);
+CHECK (offsetof (struct test_sp1, b) == 4);
+CHECK (offsetof (struct test_sp1, c) == 6);
+CHECK (offsetof (struct test_sp1, d) == 10);
+
+struct test_sp3 {
+    int a;
+    short b __attribute__((aligned(8)));
+    int c;
+    char d;
+} __attribute__((packed,ms_struct));
+
+CHECK (sizeof (struct test_sp3) == 16);
+CHECK (offsetof (struct test_sp3, a) == 0);
+CHECK (offsetof (struct test_sp3, b) == 8);
+CHECK (offsetof (struct test_sp3, c) == 10);
+CHECK (offsetof (struct test_sp3, d) == 14);
+
+struct test_s4 {
+    int a;
+    short b;
+    int c:15;
+    char d;
+} __attribute__((ms_struct));
+
+CHECK (sizeof (struct test_s4) == 16);
+CHECK (offsetof (struct test_s4, a) == 0);
+CHECK (offsetof (struct test_s4, b) == 4);
+CHECK (offsetof (struct test_s4, d) == 12);
diff --git a/gcc/testsuite/gcc.dg/bf-ms-layout-5.c b/gcc/testsuite/gcc.dg/bf-ms-layout-5.c
new file mode 100644 (file)
index 0000000..361b914
--- /dev/null
@@ -0,0 +1,45 @@
+/* PR target/52991 */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+
+struct S {
+  int a : 2;
+  __attribute__((aligned (8))) int b : 2;
+  int c : 28;
+  __attribute__((aligned (16))) int d : 2;
+  int e : 30;
+} __attribute__((ms_struct));
+
+struct S s;
+
+int
+main ()
+{
+  int i;
+  if (sizeof (s) != 32)
+    __builtin_abort ();
+  s.a = -1;
+  for (i = 0; i < 32; ++i)
+    if (((char *) &s)[i] != (i ? 0 : 3))
+      __builtin_abort ();
+  s.a = 0;
+  s.b = -1;
+  for (i = 0; i < 32; ++i)
+    if (((char *) &s)[i] != (i ? 0 : 12))
+      __builtin_abort ();
+  s.b = 0;
+  s.c = -1;
+  for (i = 0; i < 32; ++i)
+    if (((signed char *) &s)[i] != (i > 3 ? 0 : (i ? -1 : -16)))
+      __builtin_abort ();
+  s.c = 0;
+  s.d = -1;
+  for (i = 0; i < 32; ++i)
+    if (((signed char *) &s)[i] != (i == 16 ? 3 : 0))
+      __builtin_abort ();
+  s.d = 0;
+  s.e = -1;
+  for (i = 0; i < 32; ++i)
+    if (((signed char *) &s)[i] != ((i < 16 || i > 19) ? 0 : (i == 16 ? -4 : -1)))
+      __builtin_abort ();
+  return 0;
+}
index 92af9120723047b6981f37de29d8923c3414f50a..94827516f9388ffe0fdfd35767d6239f34d1da28 100644 (file)
@@ -153,27 +153,27 @@ int main(){
   struct ten test_ten;
 
 #if defined (_TEST_MS_LAYOUT) || defined (_MSC_VER)
-  size_t exp_sizeof_one = 8;
-  size_t exp_sizeof_two = 12;
+  size_t exp_sizeof_one = 12;
+  size_t exp_sizeof_two = 16;
   size_t exp_sizeof_three =6;
   size_t exp_sizeof_four = 8;
   size_t exp_sizeof_five = 3;
   size_t exp_sizeof_six = 8;
   size_t exp_sizeof_seven = 3;
-  size_t exp_sizeof_eight = 2;
+  size_t exp_sizeof_eight = 4;
   size_t exp_sizeof_nine = 8;
-  size_t exp_sizeof_ten = 8;
+  size_t exp_sizeof_ten = 16;
 
-  unsigned char exp_one_c = 7;
-  unsigned char exp_two_c  = 9;
+  unsigned char exp_one_c = 8;
+  unsigned char exp_two_c  = 12;
   unsigned char exp_three_c = 4;
   unsigned char exp_four_c = 4;
   char exp_five_c = 2;
   char exp_six_c = 5;
   char exp_seven_c = 2;
-  char exp_eight_c = 1;
+  char exp_eight_c = 2;
   char exp_nine_c = 0;
-  char exp_ten_c = 1;
+  char exp_ten_c = 8;
 
 #else /* testing -mno-ms-bitfields */