diff options
author | Roger Sayle <sayle@gcc.gnu.org> | 2007-01-30 04:39:59 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2007-01-30 04:39:59 +0000 |
commit | bcf52d7b57feb18b8839c3b0706c367c6018a876 (patch) | |
tree | 3dcbb29663a562dd3b54c1da772ca6214bb6d2c1 | |
parent | 2828987879a62a861500d4b1d5649575a07e0b78 (diff) | |
download | gcc-bcf52d7b57feb18b8839c3b0706c367c6018a876.zip gcc-bcf52d7b57feb18b8839c3b0706c367c6018a876.tar.gz gcc-bcf52d7b57feb18b8839c3b0706c367c6018a876.tar.bz2 |
fold-const.c (round_up): Make HIGH an unsigned HOST_WIDE_INT to avoid undefined behaviour on overflow.
* fold-const.c (round_up): Make HIGH an unsigned HOST_WIDE_INT to
avoid undefined behaviour on overflow. Use force_fit_type_double
to construct the constant with the specified TREE_OVERFLOW.
From-SVN: r121332
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/fold-const.c | 22 |
2 files changed, 19 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 52ec9bd..ddd35cd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,9 +1,16 @@ +2007-01-29 Roger Sayle <roger@eyesopen.com> + Richard Guenther <rguenther@suse.de> + + * fold-const.c (round_up): Make HIGH an unsigned HOST_WIDE_INT to + avoid undefined behaviour on overflow. Use force_fit_type_double + to construct the constant with the specified TREE_OVERFLOW. + 2007-01-29 Janis Johnson <janis187@us.ibm.com> * config/dfp-bit.c: Add parameterized support for fp exceptions. * config/dfp-bit.h: Ditto. -007-01-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org> +2007-01-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org> * c-decl.c (pop_scope): Replace warnings with call to warn_for_unused_label. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a7a12eb..e0cab9c 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -13514,33 +13514,33 @@ round_up (tree value, int divisor) /* If divisor is a power of two, simplify this to bit manipulation. */ if (divisor == (divisor & -divisor)) { - tree t; - if (TREE_CODE (value) == INTEGER_CST) { unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (value); - HOST_WIDE_INT high; + unsigned HOST_WIDE_INT high; + bool overflow_p; if ((low & (divisor - 1)) == 0) return value; + overflow_p = TREE_OVERFLOW (value); high = TREE_INT_CST_HIGH (value); low &= ~(divisor - 1); low += divisor; if (low == 0) - high++; - - t = build_int_cst_wide_type (TREE_TYPE (value), low, high); - if ((TREE_OVERFLOW (value) || integer_zerop (t)) - && !TREE_OVERFLOW (t)) { - t = copy_node (t); - TREE_OVERFLOW (t) = 1; + high++; + if (high == 0) + overflow_p = true; } - return t; + + return force_fit_type_double (TREE_TYPE (value), low, high, + -1, overflow_p); } else { + tree t; + t = build_int_cst (TREE_TYPE (value), divisor - 1); value = size_binop (PLUS_EXPR, value, t); t = build_int_cst (TREE_TYPE (value), -divisor); |