summaryrefslogtreecommitdiff
path: root/gcc/stor-layout.c
diff options
context:
space:
mode:
authormatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-15 12:19:49 +0000
committermatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-15 12:19:49 +0000
commit7c68c953adcf3d0744804d6011d4c8aa7ebb0a37 (patch)
tree253df9cb43aef0d0e3cdaa8b0fefeab54a75456e /gcc/stor-layout.c
parent8a6ce2102b0463164300af62a38960a551fee17e (diff)
downloadgcc-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.c42
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))