aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-04-24 19:10:55 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-04-24 19:10:55 +0000
commit77a302647e6de91919e0e9c8c2383326715e4eee (patch)
tree97a0566806e8184e997baf818e519cac788dd9bd
parent2b6da65c33c24de56b95b42c5dd2c771c425ef7c (diff)
downloadgcc-77a302647e6de91919e0e9c8c2383326715e4eee.zip
gcc-77a302647e6de91919e0e9c8c2383326715e4eee.tar.gz
gcc-77a302647e6de91919e0e9c8c2383326715e4eee.tar.bz2
tree-vrp.c (extract_range_from_binary_expr): Handle overflow from unsigned additions.
2009-04-24 Richard Guenther <rguenther@suse.de> * tree-vrp.c (extract_range_from_binary_expr): Handle overflow from unsigned additions. * gcc.dg/tree-ssa/vrp48.c: New testcase. From-SVN: r146742
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp48.c20
-rw-r--r--gcc/tree-vrp.c16
4 files changed, 45 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 51d848d..f8ee864 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 083a7e3..e5b8fff 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..a8cf8db
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp48.c
@@ -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;
+}
+
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index e3d14b2..8464ffd 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -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