diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 52ec9bdd35c..ddd35cd3be7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,9 +1,16 @@ +2007-01-29 Roger Sayle + Richard Guenther + + * 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 * config/dfp-bit.c: Add parameterized support for fp exceptions. * config/dfp-bit.h: Ditto. -007-01-29 Manuel Lopez-Ibanez +2007-01-29 Manuel Lopez-Ibanez * 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 a7a12eb1d92..e0cab9cb889 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);