This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]