diff options
author | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-15 12:19:49 +0000 |
---|---|---|
committer | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-15 12:19:49 +0000 |
commit | 7c68c953adcf3d0744804d6011d4c8aa7ebb0a37 (patch) | |
tree | 253df9cb43aef0d0e3cdaa8b0fefeab54a75456e /gcc/stor-layout.c | |
parent | 8a6ce2102b0463164300af62a38960a551fee17e (diff) | |
download | gcc-7c68c953adcf3d0744804d6011d4c8aa7ebb0a37.tar.gz |
PR middle-end/22275
* stor-layout.c (layout_decl): Zero-width bitfields aren't
influenced by maximum_field_alignment or DECL_PACKED.
(update_alignment_for_field): Ditto.
(place_field): Ditto.
* doc/extend.texi (<#pragma pack>, <Type Attributes>): Document
this behaviour.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111109 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r-- | gcc/stor-layout.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index a9879771fb2..bf25e97c629 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -339,17 +339,22 @@ layout_decl (tree decl, unsigned int known_align) /* For fields, it's a bit more complicated... */ { bool old_user_align = DECL_USER_ALIGN (decl); + bool zero_bitfield = false; + bool packed_p = DECL_PACKED (decl); + unsigned int mfa; if (DECL_BIT_FIELD (decl)) { DECL_BIT_FIELD_TYPE (decl) = type; /* A zero-length bit-field affects the alignment of the next - field. */ + field. In essence such bit-fields are not influenced by + any packing due to #pragma pack or attribute packed. */ if (integer_zerop (DECL_SIZE (decl)) - && ! DECL_PACKED (decl) && ! targetm.ms_bitfield_layout_p (DECL_FIELD_CONTEXT (decl))) { + zero_bitfield = true; + packed_p = false; #ifdef PCC_BITFIELD_TYPE_MATTERS if (PCC_BITFIELD_TYPE_MATTERS) do_type_align (type, decl); @@ -393,7 +398,7 @@ layout_decl (tree decl, unsigned int known_align) && DECL_ALIGN (decl) >= TYPE_ALIGN (type)) DECL_BIT_FIELD (decl) = 0; } - else if (DECL_PACKED (decl) && DECL_USER_ALIGN (decl)) + else if (packed_p && DECL_USER_ALIGN (decl)) /* Don't touch DECL_ALIGN. For other packed fields, go ahead and round up; we'll reduce it again below. We want packing to supersede USER_ALIGN inherited from the type, but defer to @@ -408,14 +413,14 @@ layout_decl (tree decl, unsigned int known_align) Note that do_type_align may set DECL_USER_ALIGN, so we need to check old_user_align instead. */ - if (DECL_PACKED (decl) + if (packed_p && !old_user_align && (DECL_NONADDRESSABLE_P (decl) || DECL_SIZE_UNIT (decl) == 0 || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST)) DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT); - if (! DECL_USER_ALIGN (decl) && ! DECL_PACKED (decl)) + if (! packed_p && ! DECL_USER_ALIGN (decl)) { /* Some targets (i.e. i386, VMS) limit struct field alignment to a lower boundary than alignment of variables unless @@ -429,9 +434,13 @@ layout_decl (tree decl, unsigned int known_align) #endif } + if (zero_bitfield) + mfa = initial_max_fld_align * BITS_PER_UNIT; + else + mfa = maximum_field_alignment; /* Should this be controlled by DECL_USER_ALIGN, too? */ - if (maximum_field_alignment != 0) - DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment); + if (mfa != 0) + DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), mfa); } /* Evaluate nonconstant size only once, either now or as soon as safe. */ @@ -715,7 +724,16 @@ update_alignment_for_field (record_layout_info rli, tree field, type_align = ADJUST_FIELD_ALIGN (field, type_align); #endif - if (maximum_field_alignment != 0) + /* Targets might chose to handle unnamed and hence possibly + zero-width bitfield. Those are not influenced by #pragmas + or packed attributes. */ + if (integer_zerop (DECL_SIZE (field))) + { + if (initial_max_fld_align) + type_align = MIN (type_align, + initial_max_fld_align * BITS_PER_UNIT); + } + else if (maximum_field_alignment != 0) type_align = MIN (type_align, maximum_field_alignment); else if (DECL_PACKED (field)) type_align = MIN (type_align, BITS_PER_UNIT); @@ -1177,6 +1195,10 @@ place_field (record_layout_info rli, tree field) if (DECL_BIT_FIELD_TYPE (field)) { unsigned int type_align = TYPE_ALIGN (type); + unsigned int mfa = maximum_field_alignment; + + if (integer_zerop (DECL_SIZE (field))) + mfa = initial_max_fld_align * BITS_PER_UNIT; /* Only the MS bitfields use this. We used to also put any kind of packed bit fields into prev_field, but that makes no sense, because @@ -1185,8 +1207,8 @@ place_field (record_layout_info rli, tree field) are also not fulfilled. There is no sane value to set rli->remaining_in_alignment to when a packed bitfield in prev_field is unaligned. */ - if (maximum_field_alignment != 0) - type_align = MIN (type_align, maximum_field_alignment); + if (mfa != 0) + type_align = MIN (type_align, mfa); gcc_assert (rli->prev_field || actual_align >= type_align || DECL_PACKED (field) || integer_zerop (DECL_SIZE (field)) |