aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/fold-const.c33
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr24851.c17
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;
+}
+