re PR middle-end/24851 (f2c miscompilation)

2005-11-16  Richard Guenther  <rguenther@suse.de>

	PR middle-end/24851
	* fold-const.c (extract_array_ref): Return byte offset
	in all cases.
	(fold_binary): Fold &x[a] CMP &x[b] to
	a*sizeof(*x) CMP b*sizeof(*x) to get correct overflow
	behavior.

	* gcc.c-torture/execute/pr24851.c: New testcase.

From-SVN: r107117
This commit is contained in:
Richard Guenther 2005-11-17 11:35:00 +00:00 committed by Richard Biener
parent f92af60724
commit 0bc52d42a8
4 changed files with 48 additions and 18 deletions

View File

@ -1,3 +1,12 @@
2005-11-16 Richard Guenther <rguenther@suse.de>
PR middle-end/24851
* fold-const.c (extract_array_ref): Return byte offset
in all cases.
(fold_binary): Fold &x[a] CMP &x[b] to
a*sizeof(*x) CMP b*sizeof(*x) to get correct overflow
behavior.
2005-11-16 Richard Henderson <rth@redhat.com>
PR middle-end/23497

View File

@ -5537,7 +5537,8 @@ constant_boolean_node (int value, tree type)
offset to the appropriate trees. If there is no offset,
offset is set to NULL_TREE. Base will be canonicalized to
something you can get the element type from using
TREE_TYPE (TREE_TYPE (base)). */
TREE_TYPE (TREE_TYPE (base)). Offset will be the offset
in bytes to the base. */
static bool
extract_array_ref (tree expr, tree *base, tree *offset)
@ -5573,8 +5574,10 @@ extract_array_ref (tree expr, tree *base, tree *offset)
tree op0 = TREE_OPERAND (expr, 0);
if (TREE_CODE (op0) == ARRAY_REF)
{
tree idx = TREE_OPERAND (op0, 1);
*base = TREE_OPERAND (op0, 0);
*offset = TREE_OPERAND (op0, 1);
*offset = fold_build2 (MULT_EXPR, TREE_TYPE (idx), idx,
array_ref_element_size (op0));
}
else
{
@ -8888,25 +8891,21 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& extract_array_ref (arg1, &base1, &offset1)
&& operand_equal_p (base0, base1, 0))
{
if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base0)))
&& integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base0)))))
offset0 = NULL_TREE;
if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base1)))
&& integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base1)))))
offset1 = NULL_TREE;
/* Handle no offsets on both sides specially. */
if (offset0 == NULL_TREE
&& offset1 == NULL_TREE)
{
offset0 = integer_zero_node;
offset1 = integer_zero_node;
}
else if (offset0 == NULL_TREE)
offset0 = build_int_cst (TREE_TYPE (offset1), 0);
else if (offset1 == NULL_TREE)
offset1 = build_int_cst (TREE_TYPE (offset0), 0);
return fold_build2 (code, type, integer_zero_node,
integer_zero_node);
if (TREE_TYPE (offset0) == TREE_TYPE (offset1))
return fold_build2 (code, type, offset0, offset1);
if (!offset0 || !offset1
|| TREE_TYPE (offset0) == TREE_TYPE (offset1))
{
if (offset0 == NULL_TREE)
offset0 = build_int_cst (TREE_TYPE (offset1), 0);
if (offset1 == NULL_TREE)
offset1 = build_int_cst (TREE_TYPE (offset0), 0);
return fold_build2 (code, type, offset0, offset1);
}
}
}

View File

@ -1,3 +1,8 @@
2005-11-16 Richard Guenther <rguenther@suse.de>
PR middle-end/24851
* gcc.c-torture/execute/pr24851.c: New testcase.
2005-11-16 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/fold-overflow-1.c: New test.

View File

@ -0,0 +1,17 @@
/* We used to handle pointer addition wrongly
at the time of recombining to an ARRAY_REF
in the case of
p + -4B
where -4B is represented as unsigned. */
void abort(void);
int main()
{
int a[10], *p, *q;
q = &a[1];
p = &q[-1];
if (p >= &a[9])
abort ();
return 0;
}