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/28160: Bogus error with -mms-bitfields


Hi,

PR 28160 is a 4.2 regression which is found when I've run
"make check RUNTESTFLAGS=--target_board=unix/-mms-bitfields"
on i686-linux.  With -mms-bitfields, g++ reports a bogus error
message "error: size of array 'A' is too large" for a reduced
testcase:

typedef long int along __attribute__((aligned (32)));
struct S
{
  unsigned char a;
  along d:130;
  int e:66;
} A[1];

It seems that the ms-bitfield code in stor-layout.c doesn't
take the bit field with an excessive size into account and it
makes remaining_in_alignment negative and causes the above
error.  The attached patch is to handle the bit field with
an excessive size as the case of "no remaining bits in
alignment".  How should such bit fields be processed under
the ms-bitfield layout?  I couldn't find any documents about
it.
The patch itself is 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/28160
	* stor-layout.c (place_field): Take the bit field with
	an excessive size into account in the ms-bitfiled case.

--- ORIG/trunk/gcc/stor-layout.c	2006-06-13 09:06:36.000000000 +0900
+++ LOCAL/trunk/gcc/stor-layout.c	2006-06-26 16:43:12.000000000 +0900
@@ -1047,17 +1047,20 @@ place_field (record_layout_info rli, tre
 
 	      if (rli->remaining_in_alignment < bitsize)
 		{
+		  HOST_WIDE_INT typesize = tree_low_cst (TYPE_SIZE (type), 1);
+
 		  /* out of bits; bump up to next 'word'.  */
-		  rli->offset = DECL_FIELD_OFFSET (rli->prev_field);
 		  rli->bitpos
-		    = size_binop (PLUS_EXPR, TYPE_SIZE (type),
-				  DECL_FIELD_BIT_OFFSET (rli->prev_field));
+		    = size_binop (PLUS_EXPR, rli->bitpos,
+				  bitsize_int (rli->remaining_in_alignment));
 		  rli->prev_field = field;
-		  rli->remaining_in_alignment
-		    = tree_low_cst (TYPE_SIZE (type), 1);
+		  if (typesize < bitsize)
+		    rli->remaining_in_alignment = 0;
+		  else
+		    rli->remaining_in_alignment = typesize - bitsize;
 		}
-
-	      rli->remaining_in_alignment -= bitsize;
+	      else
+		rli->remaining_in_alignment -= bitsize;
 	    }
 	  else
 	    {
@@ -1119,9 +1121,16 @@ place_field (record_layout_info rli, tre
 	  if (DECL_SIZE (field) != NULL
 	      && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 0)
 	      && host_integerp (DECL_SIZE (field), 0))
-	    rli->remaining_in_alignment
-	      = tree_low_cst (TYPE_SIZE (TREE_TYPE(field)), 1)
-		- tree_low_cst (DECL_SIZE (field), 1);
+	    {
+	      HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 1);
+	      HOST_WIDE_INT typesize
+		= tree_low_cst (TYPE_SIZE (TREE_TYPE (field)), 1);
+
+	      if (typesize < bitsize)
+		rli->remaining_in_alignment = 0;
+	      else
+		rli->remaining_in_alignment = typesize - bitsize;
+	    }
 
 	  /* Now align (conventionally) for the new type.  */
 	  type_align = TYPE_ALIGN (TREE_TYPE (field));


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