From: rguenth Date: Fri, 24 Apr 2009 19:10:55 +0000 (+0000) Subject: 2009-04-24 Richard Guenther X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=458e27ec3cc5a4ee4edc7a1ac004c1394e37427a;p=thirdparty%2Fgcc.git 2009-04-24 Richard Guenther * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 51d848d755b9..f8ee86428cfa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2009-04-24 Richard Guenther + + * tree-vrp.c (extract_range_from_binary_expr): Handle overflow + from unsigned additions. + 2009-04-24 Joseph Myers * c-typeck.c (set_init_index): Allow array designators that are diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 083a7e3efa55..e5b8fff0c848 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-04-24 Richard Guenther + + * gcc.dg/tree-ssa/vrp48.c: New testcase. + 2009-04-24 Joseph Myers * 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 000000000000..a8cf8db320bd --- /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 e3d14b291825..8464ffddd89c 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