OSDN Git Service

update copyrights
[pf3gnuchains/gcc-fork.git] / gcc / fold-const.c
index 09bc75f..b02fdaa 100644 (file)
@@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA.  */
 #include "flags.h"
 #include "tree.h"
 #include "rtl.h"
+#include "expr.h"
 #include "tm_p.h"
 #include "toplev.h"
 #include "ggc.h"
@@ -216,8 +217,11 @@ force_fit_type (t, overflow)
        TREE_INT_CST_LOW (t) &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
     }
 
-  /* Unsigned types do not suffer sign extension or overflow.  */
-  if (TREE_UNSIGNED (TREE_TYPE (t)))
+  /* Unsigned types do not suffer sign extension or overflow unless they
+     are a sizetype.  */
+  if (TREE_UNSIGNED (TREE_TYPE (t))
+      && ! (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
+           && TYPE_IS_SIZETYPE (TREE_TYPE (t))))
     return overflow;
 
   /* If the value's sign bit is set, extend the sign.  */
@@ -321,7 +325,7 @@ mul_double (l1, h1, l2, h2, lv, hv)
   encode (arg1, l1, h1);
   encode (arg2, l2, h2);
 
-  bzero ((char *) prod, sizeof prod);
+  memset ((char *) prod, 0, sizeof prod);
 
   for (i = 0; i < 4; i++)
     {
@@ -573,10 +577,10 @@ div_and_round_double (code, uns,
       goto finish_up;
     }
 
-  bzero ((char *) quo, sizeof quo);
+  memset ((char *) quo, 0, sizeof quo);
 
-  bzero ((char *) num, sizeof num);    /* to zero 9th element */
-  bzero ((char *) den, sizeof den);
+  memset ((char *) num, 0, sizeof num);        /* to zero 9th element */
+  memset ((char *) den, 0, sizeof den);
 
   encode (num, lnum, hnum);
   encode (den, lden, hden);
@@ -1039,7 +1043,7 @@ fail:
   return 1;
 }
 
-/* Convert C9X hexadecimal floating point string constant S.  Return
+/* Convert C99 hexadecimal floating point string constant S.  Return
    real value type in mode MODE.  This function uses the host computer's
    floating point arithmetic when there is no REAL_ARITHMETIC.  */
 
@@ -1604,7 +1608,8 @@ int_const_binop (code, arg1, arg2, notrunc, forsize)
       abort ();
     }
 
-  if (forsize && hi == 0 && low < 10000)
+  if (forsize && hi == 0 && low < 10000
+      && overflow == 0 && ! TREE_OVERFLOW (arg1) && ! TREE_OVERFLOW (arg2))
     return size_int_type_wide (low, TREE_TYPE (arg1));
   else
     {
@@ -1860,7 +1865,7 @@ size_int_type_wide (number, type)
   static int init_p = 0;
   tree t;
 
-  if (ggc_p && ! init_p)
+  if (! init_p)
     {
       ggc_add_tree_root ((tree *) size_table,
                         sizeof size_table / sizeof (tree));
@@ -1870,28 +1875,18 @@ size_int_type_wide (number, type)
   /* If this is a positive number that fits in the table we use to hold
      cached entries, see if it is already in the table and put it there
      if not.  */
-  if (number >= 0 && number < (int) (sizeof size_table / sizeof size_table[0]))
+  if (number >= 0 && number < (int) ARRAY_SIZE (size_table))
     {
       if (size_table[number] != 0)
        for (t = size_table[number]; t != 0; t = TREE_CHAIN (t))
          if (TREE_TYPE (t) == type)
            return t;
 
-      if (! ggc_p)
-       {
-         /* Make this a permanent node.  */
-         push_obstacks_nochange ();
-         end_temporary_allocation ();
-       }
-
       t = build_int_2 (number, 0);
       TREE_TYPE (t) = type;
       TREE_CHAIN (t) = size_table[number];
       size_table[number] = t;
 
-      if (! ggc_p)
-       pop_obstacks ();
-
       return t;
     }
 
@@ -2025,7 +2020,7 @@ fold_convert (t, arg1)
 
          /* If we are trying to make a sizetype for a small integer, use
             size_int to pick up cached types to reduce duplicate nodes.  */
-         if (TREE_CODE (type) == INTEGER_CST && TYPE_IS_SIZETYPE (type)
+         if (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
              && compare_tree_int (arg1, 10000) < 0)
            return size_int_type_wide (TREE_INT_CST_LOW (arg1), type);
 
@@ -3785,6 +3780,7 @@ fold_range_test (exp)
      short-circuited branch and the underlying object on both sides
      is the same, make a non-short-circuit operation.  */
   else if (BRANCH_COST >= 2
+          && lhs != 0 && rhs != 0
           && (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
               || TREE_CODE (exp) == TRUTH_ORIF_EXPR)
           && operand_equal_p (lhs, rhs, 0))
@@ -4402,7 +4398,8 @@ extract_muldiv (t, c, code, wide_type)
           || TREE_CODE_CLASS (TREE_CODE (op0)) == '2'
           || TREE_CODE_CLASS (TREE_CODE (op0)) == 'e')
          && TREE_UNSIGNED (TREE_TYPE (op0))
-         && ! TYPE_IS_SIZETYPE (TREE_TYPE (op0))
+         && ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
+               && TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
          && (GET_MODE_SIZE (TYPE_MODE (ctype))
               > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
        break;
@@ -4527,7 +4524,7 @@ extract_muldiv (t, c, code, wide_type)
         the operation since it will change the result if the original
         computation overflowed.  */
       if (TREE_UNSIGNED (ctype)
-         && ! TYPE_IS_SIZETYPE (ctype)
+         && ! (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype))
          && ctype != type)
        break;
 
@@ -4591,7 +4588,7 @@ extract_muldiv (t, c, code, wide_type)
         this since it will change the result if the original computation
         overflowed.  */
       if ((! TREE_UNSIGNED (ctype)
-          || TYPE_IS_SIZETYPE (ctype))
+          || (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype)))
          && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
              || (tcode == MULT_EXPR
                  && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
@@ -5103,10 +5100,10 @@ fold (expr)
             handled below, if we are converting something to its own
             type via an object of identical or wider precision, neither
             conversion is needed.  */
-         if (inside_type == final_type
+         if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (final_type)
              && ((inter_int && final_int) || (inter_float && final_float))
              && inter_prec >= final_prec)
-           return TREE_OPERAND (TREE_OPERAND (t, 0), 0);
+           return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
 
          /* Likewise, if the intermediate and final types are either both
             float or both integer, we don't need the middle conversion if
@@ -5575,7 +5572,7 @@ fold (expr)
       if (! FLOAT_TYPE_P (type))
        {
          if (! wins && integer_zerop (arg0))
-           return convert (type, negate_expr (arg1));
+           return negate_expr (convert (type, arg1));
          if (integer_zerop (arg1))
            return non_lvalue (convert (type, arg0));
 
@@ -5598,7 +5595,7 @@ fold (expr)
        {
          /* Except with IEEE floating point, 0-x equals -x.  */
          if (! wins && real_zerop (arg0))
-           return convert (type, negate_expr (arg1));
+           return negate_expr (convert (type, arg1));
          /* Except with IEEE floating point, x-0 equals x.  */
          if (real_zerop (arg1))
            return non_lvalue (convert (type, arg0));
@@ -5966,7 +5963,9 @@ fold (expr)
       /* If either arg is constant true, drop it.  */
       if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
        return non_lvalue (convert (type, arg1));
-      if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
+      if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1)
+         /* Preserve sequence points.  */
+         && (code != TRUTH_ANDIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
        return non_lvalue (convert (type, arg0));
       /* If second arg is constant zero, result is zero, but first arg
         must be evaluated.  */
@@ -6052,7 +6051,9 @@ fold (expr)
       /* If either arg is constant zero, drop it.  */
       if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
        return non_lvalue (convert (type, arg1));
-      if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1))
+      if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1)
+         /* Preserve sequence points.  */
+         && (code != TRUTH_ORIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
        return non_lvalue (convert (type, arg0));
       /* If second arg is constant true, result is true, but we must
         evaluate first arg.  */
@@ -6887,7 +6888,12 @@ fold (expr)
              {
              case EQ_EXPR:
                return
-                 pedantic_non_lvalue (convert (type, negate_expr (arg1)));
+                 pedantic_non_lvalue
+                   (convert (type,
+                             negate_expr
+                             (convert (TREE_TYPE (TREE_OPERAND (t, 1)),
+                                       arg1))));
+
              case NE_EXPR:
                return pedantic_non_lvalue (convert (type, arg1));
              case GE_EXPR:
@@ -7168,6 +7174,19 @@ fold (expr)
        return t;
       }
 
+    case CALL_EXPR:
+      /* Check for a built-in function.  */
+      if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR
+         && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0))
+             == FUNCTION_DECL)
+         && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)))
+       {
+         tree tmp = fold_builtin (expr);
+         if (tmp)
+           return tmp;
+       }
+      return t;
+
     default:
       return t;
     } /* switch (code) */
@@ -7280,8 +7299,12 @@ tree_expr_nonnegative_p (t)
       return rtl_expr_nonnegative_p (RTL_EXPR_RTL (t));
       
     default:
-      /* We don't know sign of `t', so be safe and return false.  */
-      return 0;
+      if (truth_value_p (TREE_CODE (t)))
+       /* Truth values evaluate to 0 or 1, which is nonnegative.  */
+       return 1;
+      else
+       /* We don't know sign of `t', so be conservative and return false.  */
+       return 0;
     }
 }