diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-12-23 16:39:36 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-12-23 16:39:36 +0000 |
commit | 4975da72b5d11b5c621f6bc7f3138941c91bb520 (patch) | |
tree | 159cad292d86d5201b0631ba807629fb2759076d | |
parent | 2d55cbd9d0f9d46b01c9d3d0d5817f8d226f488d (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 24 | ||||
-rw-r--r-- | gcc/stor-layout.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/i386-bitfield3.c | 24 |
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); +} |