diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/fold-const.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr24851.c | 17 |
4 files changed, 47 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f0555b3..7034cb3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0e74391..343cfae 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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) + return fold_build2 (code, type, integer_zero_node, + integer_zero_node); + + if (!offset0 || !offset1 + || TREE_TYPE (offset0) == TREE_TYPE (offset1)) { - offset0 = integer_zero_node; - offset1 = integer_zero_node; + 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); } - 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); - - if (TREE_TYPE (offset0) == TREE_TYPE (offset1)) - return fold_build2 (code, type, offset0, offset1); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c3f333..dbc0b69 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr24851.c b/gcc/testsuite/gcc.c-torture/execute/pr24851.c new file mode 100644 index 0000000..55a87e0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr24851.c @@ -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; +} + |