aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2006-02-15 12:19:49 +0000
committerMichael Matz <matz@suse.de>2006-02-15 12:19:49 +0000
commit33bf092cfbda90eef013bb2d1568ae026b7217e5 (patch)
tree253df9cb43aef0d0e3cdaa8b0fefeab54a75456e
parente99db9bf0497943be45cab3e64ee2f964ba3dfe8 (diff)
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: https://gcc.gnu.org/svn/gcc/trunk@111109 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/doc/extend.texi15
-rw-r--r--gcc/stor-layout.c42
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 <matz@suse.de>
+
+ 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.
+
2006-02-15 Paolo Bonzini <bonzini@gnu.org>
* 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))