summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2002-12-23 16:39:36 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2002-12-23 16:39:36 +0000
commit4975da72b5d11b5c621f6bc7f3138941c91bb520 (patch)
tree159cad292d86d5201b0631ba807629fb2759076d
parent2d55cbd9d0f9d46b01c9d3d0d5817f8d226f488d (diff)
downloadgcc-4975da72b5d11b5c621f6bc7f3138941c91bb520.tar.gz
* stor-layout.c (update_alignment_for_field): Correct handling of
unnamed bitfields on PCC_BITFIELD_TYPE_MATTERS machines. * doc/tm.texi (PCC_BITFIELD_TYPE_MATTERS): Note that an unnamed bitfield does not affect alignment. * testsuite/gcc.dg/i386-bitfield3.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@60439 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/doc/tm.texi24
-rw-r--r--gcc/stor-layout.c21
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/i386-bitfield3.c24
5 files changed, 62 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d066b2811db..607b179155e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2002-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ * stor-layout.c (update_alignment_for_field): Correct handling of
+ unnamed bitfields on PCC_BITFIELD_TYPE_MATTERS machines.
+ * doc/tm.texi (PCC_BITFIELD_TYPE_MATTERS): Note that an unnamed
+ bitfield does not affect alignment.
+
2002-12-23 David Edelsohn <edelsohn@gnu.org>
* expr.c (expand_assignment): Apply special treatment to
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 496a4a298dd..8436e899666 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1181,17 +1181,19 @@ go slower in that case, define this macro as 0.
Define this if you wish to imitate the way many other C compilers handle
alignment of bit-fields and the structures that contain them.
-The behavior is that the type written for a bit-field (@code{int},
-@code{short}, or other integer type) imposes an alignment for the
-entire structure, as if the structure really did contain an ordinary
-field of that type. In addition, the bit-field is placed within the
-structure so that it would fit within such a field, not crossing a
-boundary for it.
-
-Thus, on most machines, a bit-field whose type is written as @code{int}
-would not cross a four-byte boundary, and would force four-byte
-alignment for the whole structure. (The alignment used may not be four
-bytes; it is controlled by the other alignment parameters.)
+The behavior is that the type written for a named bit-field (@code{int},
+@code{short}, or other integer type) imposes an alignment for the entire
+structure, as if the structure really did contain an ordinary field of
+that type. In addition, the bit-field is placed within the structure so
+that it would fit within such a field, not crossing a boundary for it.
+
+Thus, on most machines, a named bit-field whose type is written as
+@code{int} would not cross a four-byte boundary, and would force
+four-byte alignment for the whole structure. (The alignment used may
+not be four bytes; it is controlled by the other alignment parameters.)
+
+An unnamed bit-field will not affect the alignment of the containing
+structure.
If the macro is defined, its definition should be a C expression;
a nonzero value for the expression enables this behavior.
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index c4fdaeeb91e..6c81924b69d 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -715,13 +715,9 @@ update_alignment_for_field (rli, field, known_align)
&& DECL_BIT_FIELD_TYPE (field)
&& ! integer_zerop (TYPE_SIZE (type)))
{
- /* For these machines, a zero-length field does not
- affect the alignment of the structure as a whole.
- It does, however, affect the alignment of the next field
- within the structure. */
- if (! integer_zerop (DECL_SIZE (field)))
- rli->record_align = MAX (rli->record_align, desired_align);
- else if (! DECL_PACKED (field))
+ /* A zero-length bit-field affects the alignment of the next
+ field. */
+ if (!DECL_PACKED (field) && integer_zerop (DECL_SIZE (field)))
{
desired_align = TYPE_ALIGN (type);
#ifdef ADJUST_FIELD_ALIGN
@@ -729,8 +725,8 @@ update_alignment_for_field (rli, field, known_align)
#endif
}
- /* A named bit field of declared type `int'
- forces the entire structure to have `int' alignment. */
+ /* Named bit-fields cause the entire structure to have the
+ alignment implied by their type. */
if (DECL_NAME (field) != 0)
{
unsigned int type_align = TYPE_ALIGN (type);
@@ -745,7 +741,14 @@ update_alignment_for_field (rli, field, known_align)
else if (DECL_PACKED (field))
type_align = MIN (type_align, BITS_PER_UNIT);
+ /* The alignment of the record is increased to the maximum
+ of the current alignment, the alignment indicated on the
+ field (i.e., the alignment specified by an __aligned__
+ attribute), and the alignment indicated by the type of
+ the field. */
+ rli->record_align = MAX (rli->record_align, desired_align);
rli->record_align = MAX (rli->record_align, type_align);
+
rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
if (warn_packed)
rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index db2e5f57900..c4011100dac 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2002-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ * testsuite/gcc.dg/i386-bitfield3.c: New test.
+
+ * testsuite/gcc.dg/i386-bitfield2.c: New test.
+
2002-12-22 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/parse/conv_op1.C: New test.
diff --git a/gcc/testsuite/gcc.dg/i386-bitfield3.c b/gcc/testsuite/gcc.dg/i386-bitfield3.c
new file mode 100644
index 00000000000..781c2f7ba4e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/i386-bitfield3.c
@@ -0,0 +1,24 @@
+// Test for bitfield alignment in structs on IA-32
+// { dg-do run { target i?86-*-* } }
+// { dg-options "-O2" }
+// { dg-options "-mno-align-double -mno-ms-bitfields" { target *-*-interix* } }
+
+extern void abort (void);
+extern void exit (int);
+
+struct X {
+ int : 32;
+};
+
+struct Y {
+ int i : 32;
+};
+
+int main () {
+ if (__alignof__(struct X) != 1)
+ abort ();
+ if (__alignof__(struct Y) != 4)
+ abort ();
+
+ exit (0);
+}