OSDN Git Service

2009-04-24 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Apr 2009 19:10:55 +0000 (19:10 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Apr 2009 19:10:55 +0000 (19:10 +0000)
* tree-vrp.c (extract_range_from_binary_expr): Handle overflow
from unsigned additions.

* gcc.dg/tree-ssa/vrp48.c: New testcase.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/vrp48.c [new file with mode: 0644]
gcc/tree-vrp.c

index 51d848d..f8ee864 100644 (file)
@@ -1,3 +1,8 @@
+2009-04-24  Richard Guenther  <rguenther@suse.de>
+
+       * tree-vrp.c (extract_range_from_binary_expr): Handle overflow
+       from unsigned additions.
+
 2009-04-24  Joseph Myers  <joseph@codesourcery.com>
 
        * c-typeck.c (set_init_index): Allow array designators that are
index 083a7e3..e5b8fff 100644 (file)
@@ -1,3 +1,7 @@
+2009-04-24  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/vrp48.c: New testcase.
+
 2009-04-24  Joseph Myers  <joseph@codesourcery.com>
 
        * gcc.dg/array-const-1.c, gcc.dg/array-const-2.c,
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp48.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp48.c
new file mode 100644 (file)
index 0000000..a8cf8db
--- /dev/null
@@ -0,0 +1,20 @@
+extern void link_failure (void);
+
+static int __attribute__ ((noinline)) foo (int x)
+{
+  if (x >= 1)
+    if (x <= 10)
+      {
+       if (x < 1 || x > 10)
+         link_failure ();
+       x = x + 1;
+      }
+  return x;
+}
+
+int main (void)
+{
+  int i = foo (0);
+  return 0;
+}
+
index e3d14b2..8464ffd 100644 (file)
@@ -2248,6 +2248,22 @@ extract_range_from_binary_expr (value_range_t *vr,
         the same end of each range.  */
       min = vrp_int_const_binop (code, vr0.min, vr1.min);
       max = vrp_int_const_binop (code, vr0.max, vr1.max);
+
+      /* If both additions overflowed the range kind is still correct.
+        This happens regularly with subtracting something in unsigned
+        arithmetic.
+         ???  See PR30318 for all the cases we do not handle.  */
+      if (code == PLUS_EXPR
+         && (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
+         && (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
+       {
+         min = build_int_cst_wide (TREE_TYPE (min),
+                                   TREE_INT_CST_LOW (min),
+                                   TREE_INT_CST_HIGH (min));
+         max = build_int_cst_wide (TREE_TYPE (max),
+                                   TREE_INT_CST_LOW (max),
+                                   TREE_INT_CST_HIGH (max));
+       }
     }
   else if (code == MULT_EXPR
           || code == TRUNC_DIV_EXPR