From 33bf092cfbda90eef013bb2d1568ae026b7217e5 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Wed, 15 Feb 2006 12:19:49 +0000 Subject: 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>, ): Document this behaviour. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@111109 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++++++++ gcc/doc/extend.texi | 15 ++++++++------- gcc/stor-layout.c | 42 ++++++++++++++++++++++++++++++++---------- 3 files changed, 51 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a5ed7445b3a..2a287c0e90c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2006-02-15 Michael Matz + + 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>, ): Document + this behaviour. + 2006-02-15 Paolo Bonzini * cfg.c (dump_flow_info): Get dump flags as an additional parameter. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a20349d8488..cf1545826b9 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3329,9 +3329,10 @@ alignment. See your linker documentation for further information. @item packed This attribute, attached to @code{struct} or @code{union} type -definition, specifies that each member of the structure or union is -placed to minimize the memory required. When attached to an @code{enum} -definition, it indicates that the smallest integral type should be used. +definition, specifies that each member (other than zero-width bitfields) +of the structure or union is placed to minimize the memory required. When +attached to an @code{enum} definition, it indicates that the smallest +integral type should be used. @opindex fshort-enums Specifying this attribute for @code{struct} and @code{union} types is @@ -9518,10 +9519,10 @@ way of knowing that that happened.) @subsection Structure-Packing Pragmas For compatibility with Win32, GCC supports a set of @code{#pragma} -directives which change the maximum alignment of members of structures, -unions, and classes subsequently defined. The @var{n} value below always -is required to be a small power of two and specifies the new alignment -in bytes. +directives which change the maximum alignment of members of structures +(other than zero-width bitfields), unions, and classes subsequently +defined. The @var{n} value below always is required to be a small power +of two and specifies the new alignment in bytes. @enumerate @item @code{#pragma pack(@var{n})} simply sets the new alignment. 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)) -- cgit v1.2.3