From 0bc52d42a8a8c376f9d13a9ea1d5739b6dc3a195 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Thu, 17 Nov 2005 11:35:00 +0000 Subject: [PATCH] re PR middle-end/24851 (f2c miscompilation) 2005-11-16 Richard Guenther 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 --- gcc/ChangeLog | 9 +++++ gcc/fold-const.c | 35 +++++++++---------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.c-torture/execute/pr24851.c | 17 +++++++++ 4 files changed, 48 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr24851.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f0555b3b982..7034cb3c7f7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2005-11-16 Richard Guenther + + 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 PR middle-end/23497 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0e74391fe51..343cfae6903 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) - { - 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); + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c3f333ddd7..dbc0b69f2db 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-11-16 Richard Guenther + + PR middle-end/24851 + * gcc.c-torture/execute/pr24851.c: New testcase. + 2005-11-16 Eric Botcazou * 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 00000000000..55a87e0019e --- /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; +} +