* fold-const.c (round_up): Make HIGH an unsigned HOST_WIDE_INT to
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Jan 2007 04:39:59 +0000 (04:39 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Jan 2007 04:39:59 +0000 (04:39 +0000)
avoid undefined behaviour on overflow.  Use force_fit_type_double
to construct the constant with the specified TREE_OVERFLOW.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121332 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c

index 52ec9bd..ddd35cd 100644 (file)
@@ -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.
index a7a12eb..e0cab9c 100644 (file)
@@ -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);