[Bug target/52991] [6/7/8 Regression] attribute packed broken on mingw32?
dev at benjarobin dot fr
gcc-bugzilla@gcc.gnu.org
Fri Dec 29 22:04:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991
--- Comment #26 from Benjamin Robin <dev at benjarobin dot fr> ---
I try to work on this bug, by curiosity... And I did found 3 bug in the current
layout of structure when ms_bitfield_layout_p = 1:
**************************
1) Basic packing (the failing test):
--------------------------
PACK(struct test_sp1 {
int a;
short b;
int c;
char d;
});
assert_cc(sizeof(struct test_sp1) == 11);
assert_cc(offsetof(struct test_sp1, a) == 0);
assert_cc(offsetof(struct test_sp1, b) == 4);
assert_cc(offsetof(struct test_sp1, c) == 6);
assert_cc(offsetof(struct test_sp1, d) == 10);
--------------------------
Associated Patch :
--------------------------
@@ -1460,7 +1475,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);
--------------------------
**************************
2) Struct packing that contains a field with an aligned attribute
(the failing test):
--------------------------
PACK(struct test_sp3 {
int a;
ALIGN(short b, 8);
int c;
char d;
});
assert_cc(sizeof(struct test_sp3) == 16);
assert_cc(offsetof(struct test_sp3, a) == 0);
assert_cc(offsetof(struct test_sp3, b) == 8);
assert_cc(offsetof(struct test_sp3, c) == 10);
assert_cc(offsetof(struct test_sp3, d) == 14);
--------------------------
Associated Patch :
--------------------------
@@ -1018,8 +1018,13 @@ update_alignment_for_field (record_layout_info rli, tree
field,
if (maximum_field_alignment != 0)
type_align = MIN (type_align, maximum_field_alignment);
rli->record_align = MAX (rli->record_align, type_align);
- rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
- }
+ }
+ else
+ {
+ rli->record_align = MAX (rli->record_align, desired_align);
+ }
+
+ rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
}
else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
{
--------------------------
**************************
3) Struct with a bit-field followed by a char (the failing test):
--------------------------
struct test_s4 {
int a;
short b;
int c:15;
char d;
};
#ifdef _WIN32
assert_cc(sizeof(struct test_s4) == 16);
assert_cc(offsetof(struct test_s4, a) == 0);
assert_cc(offsetof(struct test_s4, b) == 4);
assert_cc(offsetof(struct test_s4, d) == 12);
#else
assert_cc(sizeof(struct test_s4) == 12);
assert_cc(offsetof(struct test_s4, a) == 0);
assert_cc(offsetof(struct test_s4, b) == 4);
assert_cc(offsetof(struct test_s4, d) == 8);
#endif
--------------------------
Associated Patch :
--------------------------
@@ -1218,9 +1223,21 @@ place_field (record_layout_info rli, tree field)
/* No, we need to skip space before this field.
Bump the cumulative size to multiple of field alignment. */
- if (!targetm.ms_bitfield_layout_p (rli->t)
- && DECL_SOURCE_LOCATION (field) != BUILTINS_LOCATION)
- warning (OPT_Wpadded, "padding struct to align %q+D", field);
+ if (targetm.ms_bitfield_layout_p (rli->t))
+ {
+ if (rli->prev_field != NULL &&
+ !integer_zerop (DECL_SIZE (rli->prev_field)) )
+ {
+ rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos,
+ bitsize_int (rli->remaining_in_alignment));
+ }
+ rli->prev_field = NULL;
+ }
+ else
+ {
+ if (DECL_SOURCE_LOCATION (field) != BUILTINS_LOCATION)
+ warning (OPT_Wpadded, "padding struct to align %q+D", field);
+ }
/* If the alignment is still within offset_align, just align
the bit position. */
--------------------------
************************
*) Macro used in the code above
--------------------------
#ifdef _WIN32
# ifdef _MSC_VER
# define PACK(typeDec) __pragma( pack(push, 1) ) typeDec __pragma( pack(pop) )
# else
# define PACK(typeDec) typeDec __attribute__((__packed__,ms_struct))
# endif
#else
# define PACK(typeDec) typeDec __attribute__((__packed__))
#endif
#ifdef _MSC_VER
# define ALIGN(typeDec, n) __declspec(align(n)) typeDec
#else
# define ALIGN(typeDec, n) typeDec __attribute__((aligned(n)))
#endif
--------------------------
More information about the Gcc-bugs
mailing list