OSDN Git Service

2005-11-16 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 17 Nov 2005 11:35:00 +0000 (11:35 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 17 Nov 2005 11:35:00 +0000 (11:35 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107117 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr24851.c [new file with mode: 0644]

index f0555b3..7034cb3 100644 (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
index 0e74391..343cfae 100644 (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)
+               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);
            }
        }
 
index 9c3f333..dbc0b69 100644 (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.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr24851.c b/gcc/testsuite/gcc.c-torture/execute/pr24851.c
new file mode 100644 (file)
index 0000000..55a87e0
--- /dev/null
@@ -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;
+}
+