Blame SOURCES/gcc48-pr58970.patch

543165
2013-11-06  Jakub Jelinek  <jakub@redhat.com>
543165
543165
	PR middle-end/58970
543165
	* expr.c (get_bit_range): Handle *offset == NULL_TREE.
543165
	(expand_assignment): If *bitpos is negative, set *offset
543165
	and adjust *bitpos, so that it is not negative.
543165
543165
	* gcc.c-torture/compile/pr58970-1.c: New test.
543165
	* gcc.c-torture/compile/pr58970-2.c: New test.
543165
543165
--- gcc/expr.c	(revision 204443)
543165
+++ gcc/expr.c	(revision 204444)
543165
@@ -4576,19 +4576,19 @@ get_bit_range (unsigned HOST_WIDE_INT *b
543165
 		- tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
543165
 
543165
   /* If the adjustment is larger than bitpos, we would have a negative bit
543165
-     position for the lower bound and this may wreak havoc later.  This can
543165
-     occur only if we have a non-null offset, so adjust offset and bitpos
543165
-     to make the lower bound non-negative.  */
543165
+     position for the lower bound and this may wreak havoc later.  Adjust
543165
+     offset and bitpos to make the lower bound non-negative in that case.  */
543165
   if (bitoffset > *bitpos)
543165
     {
543165
       HOST_WIDE_INT adjust = bitoffset - *bitpos;
543165
-
543165
       gcc_assert ((adjust % BITS_PER_UNIT) == 0);
543165
-      gcc_assert (*offset != NULL_TREE);
543165
 
543165
       *bitpos += adjust;
543165
-      *offset
543165
-	= size_binop (MINUS_EXPR, *offset, size_int (adjust / BITS_PER_UNIT));
543165
+      if (*offset == NULL_TREE)
543165
+	*offset = size_int (-adjust / BITS_PER_UNIT);
543165
+      else
543165
+	*offset
543165
+	  = size_binop (MINUS_EXPR, *offset, size_int (adjust / BITS_PER_UNIT));
543165
       *bitstart = 0;
543165
     }
543165
   else
543165
@@ -4721,6 +4721,15 @@ expand_assignment (tree to, tree from, b
543165
       tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
543165
 				 &unsignedp, &volatilep, true);
543165
 
543165
+      /* Make sure bitpos is not negative, it can wreak havoc later.  */
543165
+      if (bitpos < 0)
543165
+	{
543165
+	  gcc_assert (offset == NULL_TREE);
543165
+	  offset = size_int (bitpos >> (BITS_PER_UNIT == 8
543165
+					? 3 : exact_log2 (BITS_PER_UNIT)));
543165
+	  bitpos &= BITS_PER_UNIT - 1;
543165
+	}
543165
+
543165
       if (TREE_CODE (to) == COMPONENT_REF
543165
 	  && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
543165
 	get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);
543165
--- gcc/testsuite/gcc.c-torture/compile/pr58970-1.c	(revision 0)
543165
+++ gcc/testsuite/gcc.c-torture/compile/pr58970-1.c	(revision 204444)
543165
@@ -0,0 +1,11 @@
543165
+/* PR middle-end/58970 */
543165
+
543165
+struct T { int b : 1; };
543165
+struct S { struct T t[1]; };
543165
+
543165
+void
543165
+foo (int x, struct S *s)
543165
+{
543165
+  if (x == -1)
543165
+    s->t[x].b = 0;
543165
+}
543165
--- gcc/testsuite/gcc.c-torture/compile/pr58970-2.c	(revision 0)
543165
+++ gcc/testsuite/gcc.c-torture/compile/pr58970-2.c	(revision 204444)
543165
@@ -0,0 +1,11 @@
543165
+/* PR middle-end/58970 */
543165
+
543165
+struct T { char a : 8; char b : 1; };
543165
+struct S { char x; struct T t[1]; };
543165
+
543165
+void
543165
+foo (int x, struct S *s)
543165
+{
543165
+  if (x == -1)
543165
+    s->t[x].b = 0;
543165
+}