@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
@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.
/* 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);
&& 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
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
#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. */
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);
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
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))