This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch RFC] PR middle-end/28161: Wrong bit field layout with -mms-bitfields
- From: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Jun 2006 08:17:56 +0900 (JST)
- Subject: [patch RFC] PR middle-end/28161: Wrong bit field layout with -mms-bitfields
PR 28161 is another 4.2 regression with -mms-bitfields.
A reduced testcase of a tmpdir-g++.dg-struct-layout-1
test is
extern "C" void abort (void);
struct S
{
long long d:23;
int e:32;
int f:32;
} a;
int main (void)
{
a.e = -3;
a.f = 1;
if (a.e != -3)
abort ();
return 0;
}
which shows that the current compiler allocates a.e and a.f in
an overlapped manner with -mms-bitfields.
When processing the consecutive bit fields in the ms-bitfield
layout, place_field compares the size of type of a bit field
with that of the previous one. It seems that TREE_TYPE of
the previous bit filed is already cooked at that point and
might be changed to the smaller type. The appended patch is
to make place_field use DECL_BIT_FIELD_TYPE of the previous
bit field instead of TREE_TYPE. With it, all runtime errors
for struct-layout-1 g++ tests with -mms-bitfields went away on
i686-pc-linux-gnu.
Tested with bootstrap and the top level "make -k check" with no
new failures on i686-pc-linux-gnu and i686-pc-cygwin.
Regards,
kaz
--
:ADDPATCH middle-end:
2006-06-28 Kaz Kojima <kkojima@gcc.gnu.org>
PR middle-end/28161
* stor-layout.c (place_field): Use DECL_BIT_FIELD_TYPE of
the previous bit field.
--- ORIG/trunk/gcc/stor-layout.c 2006-06-13 09:06:36.000000000 +0900
+++ LOCAL/trunk/gcc/stor-layout.c 2006-06-26 16:44:31.000000000 +0900
@@ -1022,6 +1022,7 @@ place_field (record_layout_info rli, tre
if (targetm.ms_bitfield_layout_p (rli->t))
{
tree prev_saved = rli->prev_field;
+ tree prev_type = prev_saved ? DECL_BIT_FIELD_TYPE (prev_saved) : NULL;
/* This is a bitfield if it exists. */
if (rli->prev_field)
@@ -1037,8 +1038,7 @@ place_field (record_layout_info rli, tre
&& !integer_zerop (DECL_SIZE (rli->prev_field))
&& host_integerp (DECL_SIZE (rli->prev_field), 0)
&& host_integerp (TYPE_SIZE (type), 0)
- && simple_cst_equal (TYPE_SIZE (type),
- TYPE_SIZE (TREE_TYPE (rli->prev_field))))
+ && simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type)))
{
/* We're in the middle of a run of equal type size fields; make
sure we realign if we run out of bits. (Not decl size,
@@ -1105,8 +1108,7 @@ place_field (record_layout_info rli, tre
if (!DECL_BIT_FIELD_TYPE (field)
|| (prev_saved != NULL
- ? !simple_cst_equal (TYPE_SIZE (type),
- TYPE_SIZE (TREE_TYPE (prev_saved)))
+ ? !simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type))
: !integer_zerop (DECL_SIZE (field)) ))
{
/* Never smaller than a byte for compatibility. */