mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-11 03:50:27 +08:00
re PR middle-end/31115 (libstdc++ 22_locale/num_get/get/char/2.cc 27_io/basic_ostream/inserters_arithmetic/char/6.cc)
2007-03-11 Richard Guenther <rguenther@suse.de> PR tree-optimization/31115 * tree-vrp.c (extract_range_from_binary_expr): Make sure the shift count is positive and non-anti-range for RSHIFT_EXPR. A shift count of zero is not special as with *_DIV_EXPR. (vrp_int_const_binop): Handle RSHIFT_EXPR for determining overflow direction. * gcc.dg/torture/pr31115.c: New testcase. From-SVN: r122821
This commit is contained in:
parent
d7419dec45
commit
13338552e2
@ -1,3 +1,12 @@
|
||||
2007-03-11 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/31115
|
||||
* tree-vrp.c (extract_range_from_binary_expr): Make sure
|
||||
the shift count is positive and non-anti-range for RSHIFT_EXPR.
|
||||
A shift count of zero is not special as with *_DIV_EXPR.
|
||||
(vrp_int_const_binop): Handle RSHIFT_EXPR for determining overflow
|
||||
direction.
|
||||
|
||||
2007-03-11 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* tree-vrp.c (vrp_int_const_binop): Handle PLUS_EXPR and
|
||||
|
@ -1,3 +1,8 @@
|
||||
2007-03-11 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/31115
|
||||
* gcc.dg/torture/pr31115.c: New testcase.
|
||||
|
||||
2007-03-11 Ira Rosen <irar@il.ibm.com>
|
||||
|
||||
PR tree-optimization/29925
|
||||
|
22
gcc/testsuite/gcc.dg/torture/pr31115.c
Normal file
22
gcc/testsuite/gcc.dg/torture/pr31115.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* { dg-do run } */
|
||||
|
||||
extern void exit(int);
|
||||
extern void abort();
|
||||
void foo (int e1)
|
||||
{
|
||||
if (e1 < 0)
|
||||
{
|
||||
e1 = -e1;
|
||||
if (e1 >>= 4)
|
||||
{
|
||||
if (e1 >= 1 << 5)
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
foo(-(1<<9));
|
||||
abort();
|
||||
}
|
@ -1569,6 +1569,12 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
|
||||
&& (sgn1 >= 0
|
||||
? !is_positive_overflow_infinity (val2)
|
||||
: is_negative_overflow_infinity (val2)))
|
||||
/* We only get in here with positive shift count, so the
|
||||
overflow direction is the same as the sign of val1.
|
||||
Actually rshift does not overflow at all, but we only
|
||||
handle the case of shifting overflowed -INF and +INF. */
|
||||
|| (code == RSHIFT_EXPR
|
||||
&& sgn1 >= 0)
|
||||
/* For division, the only case is -INF / -1 = +INF. */
|
||||
|| code == TRUNC_DIV_EXPR
|
||||
|| code == FLOOR_DIV_EXPR
|
||||
@ -1802,6 +1808,17 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we have a RSHIFT_EXPR with a possibly negative shift
|
||||
count or an anti-range shift count drop to VR_VARYING.
|
||||
We currently cannot handle the overflow cases correctly. */
|
||||
if (code == RSHIFT_EXPR
|
||||
&& (vr1.type == VR_ANTI_RANGE
|
||||
|| !vrp_expr_computes_nonnegative (op1, &sop)))
|
||||
{
|
||||
set_value_range_to_varying (vr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Multiplications and divisions are a bit tricky to handle,
|
||||
depending on the mix of signs we have in the two ranges, we
|
||||
need to operate on different values to get the minimum and
|
||||
@ -1816,7 +1833,8 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
|
||||
the new range. */
|
||||
|
||||
/* Divisions by zero result in a VARYING value. */
|
||||
if (code != MULT_EXPR
|
||||
if ((code != MULT_EXPR
|
||||
&& code != RSHIFT_EXPR)
|
||||
&& (vr0.type == VR_ANTI_RANGE || range_includes_zero_p (&vr1)))
|
||||
{
|
||||
set_value_range_to_varying (vr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user