re PR middle-end/58970 (internal compiler error: in get_bit_range, at expr.c:4562)

PR middle-end/58970
	* expr.c (get_bit_range): Handle *offset == NULL_TREE.
	(expand_assignment): If *bitpos is negative, set *offset
	and adjust *bitpos, so that it is not negative.

	* gcc.c-torture/compile/pr58970.c: New test.

From-SVN: r204444
This commit is contained in:
Jakub Jelinek 2013-11-06 08:48:50 +01:00 committed by Jakub Jelinek
parent 10180dd302
commit fda1ba0aea
5 changed files with 50 additions and 7 deletions

View file

@ -1,3 +1,10 @@
2013-11-06 Jakub Jelinek <jakub@redhat.com>
PR middle-end/58970
* expr.c (get_bit_range): Handle *offset == NULL_TREE.
(expand_assignment): If *bitpos is negative, set *offset
and adjust *bitpos, so that it is not negative.
2013-11-06 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
* config/i386/bdver3.md : Added two additional decoder units

View file

@ -4576,19 +4576,19 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
- tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
/* If the adjustment is larger than bitpos, we would have a negative bit
position for the lower bound and this may wreak havoc later. This can
occur only if we have a non-null offset, so adjust offset and bitpos
to make the lower bound non-negative. */
position for the lower bound and this may wreak havoc later. Adjust
offset and bitpos to make the lower bound non-negative in that case. */
if (bitoffset > *bitpos)
{
HOST_WIDE_INT adjust = bitoffset - *bitpos;
gcc_assert ((adjust % BITS_PER_UNIT) == 0);
gcc_assert (*offset != NULL_TREE);
*bitpos += adjust;
*offset
= size_binop (MINUS_EXPR, *offset, size_int (adjust / BITS_PER_UNIT));
if (*offset == NULL_TREE)
*offset = size_int (-adjust / BITS_PER_UNIT);
else
*offset
= size_binop (MINUS_EXPR, *offset, size_int (adjust / BITS_PER_UNIT));
*bitstart = 0;
}
else
@ -4721,6 +4721,15 @@ expand_assignment (tree to, tree from, bool nontemporal)
tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
&unsignedp, &volatilep, true);
/* Make sure bitpos is not negative, it can wreak havoc later. */
if (bitpos < 0)
{
gcc_assert (offset == NULL_TREE);
offset = size_int (bitpos >> (BITS_PER_UNIT == 8
? 3 : exact_log2 (BITS_PER_UNIT)));
bitpos &= BITS_PER_UNIT - 1;
}
if (TREE_CODE (to) == COMPONENT_REF
&& DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);

View file

@ -1,3 +1,8 @@
2013-11-06 Jakub Jelinek <jakub@redhat.com>
PR middle-end/58970
* gcc.c-torture/compile/pr58970.c: New test.
2013-11-05 Wei Mi <wmi@google.com>
PR regression/58985

View file

@ -0,0 +1,11 @@
/* PR middle-end/58970 */
struct T { int b : 1; };
struct S { struct T t[1]; };
void
foo (int x, struct S *s)
{
if (x == -1)
s->t[x].b = 0;
}

View file

@ -0,0 +1,11 @@
/* PR middle-end/58970 */
struct T { char a : 8; char b : 1; };
struct S { char x; struct T t[1]; };
void
foo (int x, struct S *s)
{
if (x == -1)
s->t[x].b = 0;
}