OSDN Git Service

Always dereference nil receiver passed to value method.
[pf3gnuchains/gcc-fork.git] / gcc / tree-cfg.c
index 349f56e..20feff9 100644 (file)
@@ -1421,7 +1421,7 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b)
   if (!single_succ_p (a))
     return false;
 
-  if (single_succ_edge (a)->flags & (EDGE_ABNORMAL | EDGE_EH))
+  if (single_succ_edge (a)->flags & (EDGE_ABNORMAL | EDGE_EH | EDGE_PRESERVE))
     return false;
 
   if (single_succ (a) != b)
@@ -1566,9 +1566,11 @@ replace_uses_by (tree name, tree val)
 
       if (gimple_code (stmt) != GIMPLE_PHI)
        {
+         gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
          size_t i;
 
-         fold_stmt_inplace (stmt);
+         fold_stmt (&gsi);
+         stmt = gsi_stmt (gsi);
          if (cfgcleanup_altered_bbs && !is_gimple_debug (stmt))
            bitmap_set_bit (cfgcleanup_altered_bbs, gimple_bb (stmt)->index);
 
@@ -2680,7 +2682,8 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
       break;
 
     case NON_LVALUE_EXPR:
-       gcc_unreachable ();
+    case TRUTH_NOT_EXPR:
+      gcc_unreachable ();
 
     CASE_CONVERT:
     case FIX_TRUNC_EXPR:
@@ -2688,7 +2691,6 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
     case NEGATE_EXPR:
     case ABS_EXPR:
     case BIT_NOT_EXPR:
-    case TRUTH_NOT_EXPR:
       CHECK_OP (0, "invalid operand to unary operator");
       break;
 
@@ -2772,13 +2774,11 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
          error ("invalid operand to pointer plus, first operand is not a pointer");
          return t;
        }
-      /* Check to make sure the second operand is an integer with type of
-        sizetype.  */
-      if (!useless_type_conversion_p (sizetype,
-                                    TREE_TYPE (TREE_OPERAND (t, 1))))
+      /* Check to make sure the second operand is a ptrofftype.  */
+      if (!ptrofftype_p (TREE_TYPE (TREE_OPERAND (t, 1))))
        {
          error ("invalid operand to pointer plus, second operand is not an "
-                "integer with type of sizetype");
+                "integer type of appropriate width");
          return t;
        }
       /* FALLTHROUGH */
@@ -3195,23 +3195,55 @@ verify_gimple_comparison (tree type, tree op0, tree op1)
      effective type the comparison is carried out in.  Instead
      we require that either the first operand is trivially
      convertible into the second, or the other way around.
-     The resulting type of a comparison may be any integral type.
      Because we special-case pointers to void we allow
      comparisons of pointers with the same mode as well.  */
-  if ((!useless_type_conversion_p (op0_type, op1_type)
-       && !useless_type_conversion_p (op1_type, op0_type)
-       && (!POINTER_TYPE_P (op0_type)
-          || !POINTER_TYPE_P (op1_type)
-          || TYPE_MODE (op0_type) != TYPE_MODE (op1_type)))
-      || !INTEGRAL_TYPE_P (type))
-    {
-      error ("type mismatch in comparison expression");
-      debug_generic_expr (type);
+  if (!useless_type_conversion_p (op0_type, op1_type)
+      && !useless_type_conversion_p (op1_type, op0_type)
+      && (!POINTER_TYPE_P (op0_type)
+         || !POINTER_TYPE_P (op1_type)
+         || TYPE_MODE (op0_type) != TYPE_MODE (op1_type)))
+    {
+      error ("mismatching comparison operand types");
       debug_generic_expr (op0_type);
       debug_generic_expr (op1_type);
       return true;
     }
 
+  /* The resulting type of a comparison may be an effective boolean type.  */
+  if (INTEGRAL_TYPE_P (type)
+      && (TREE_CODE (type) == BOOLEAN_TYPE
+         || TYPE_PRECISION (type) == 1))
+    ;
+  /* Or an integer vector type with the same size and element count
+     as the comparison operand types.  */
+  else if (TREE_CODE (type) == VECTOR_TYPE
+          && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE)
+    {
+      if (TREE_CODE (op0_type) != VECTOR_TYPE
+         || TREE_CODE (op1_type) != VECTOR_TYPE)
+        {
+          error ("non-vector operands in vector comparison");
+          debug_generic_expr (op0_type);
+          debug_generic_expr (op1_type);
+          return true;
+        }
+
+      if (TYPE_VECTOR_SUBPARTS (type) != TYPE_VECTOR_SUBPARTS (op0_type)
+         || (GET_MODE_SIZE (TYPE_MODE (type))
+             != GET_MODE_SIZE (TYPE_MODE (op0_type))))
+        {
+          error ("invalid vector comparison resulting type");
+          debug_generic_expr (type);
+          return true;
+        }
+    }
+  else
+    {
+      error ("bogus comparison result type");
+      debug_generic_expr (type);
+      return true;
+    }
+
   return false;
 }
 
@@ -3246,17 +3278,17 @@ verify_gimple_assign_unary (gimple stmt)
       {
        /* Allow conversions between integral types and pointers only if
           there is no sign or zero extension involved.
-          For targets were the precision of sizetype doesn't match that
+          For targets were the precision of ptrofftype doesn't match that
           of pointers we need to allow arbitrary conversions from and
-          to sizetype.  */
+          to ptrofftype.  */
        if ((POINTER_TYPE_P (lhs_type)
             && INTEGRAL_TYPE_P (rhs1_type)
             && (TYPE_PRECISION (lhs_type) >= TYPE_PRECISION (rhs1_type)
-                || rhs1_type == sizetype))
+                || ptrofftype_p (rhs1_type)))
            || (POINTER_TYPE_P (rhs1_type)
                && INTEGRAL_TYPE_P (lhs_type)
                && (TYPE_PRECISION (rhs1_type) >= TYPE_PRECISION (lhs_type)
-                   || lhs_type == sizetype)))
+                   || ptrofftype_p (sizetype))))
          return false;
 
        /* Allow conversion from integer to offset type and vice versa.  */
@@ -3344,19 +3376,6 @@ verify_gimple_assign_unary (gimple stmt)
       /* FIXME.  */
       return false;
 
-    case TRUTH_NOT_EXPR:
-      /* We require two-valued operand types.  */
-      if (!(TREE_CODE (rhs1_type) == BOOLEAN_TYPE
-           || (INTEGRAL_TYPE_P (rhs1_type)
-               && TYPE_PRECISION (rhs1_type) == 1)))
-        {
-         error ("invalid types in truth not");
-         debug_generic_expr (lhs_type);
-         debug_generic_expr (rhs1_type);
-         return true;
-        }
-      break;
-
     case NEGATE_EXPR:
     case ABS_EXPR:
     case BIT_NOT_EXPR:
@@ -3536,7 +3555,7 @@ verify_gimple_assign_binary (gimple stmt)
 do_pointer_plus_expr_check:
        if (!POINTER_TYPE_P (rhs1_type)
            || !useless_type_conversion_p (lhs_type, rhs1_type)
-           || !useless_type_conversion_p (sizetype, rhs2_type))
+           || !ptrofftype_p (rhs2_type))
          {
            error ("type mismatch in pointer plus expression");
            debug_generic_stmt (lhs_type);
@@ -3577,7 +3596,7 @@ do_pointer_plus_expr_check:
     case WIDEN_MULT_EXPR:
       if (TREE_CODE (lhs_type) != INTEGER_TYPE)
        return true;
-      return ((2 * TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (lhs_type))
+      return ((2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type))
              || (TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type)));
 
     case WIDEN_SUM_EXPR:
@@ -3651,7 +3670,8 @@ verify_gimple_assign_ternary (gimple stmt)
       return true;
     }
 
-  if (!is_gimple_val (rhs1)
+  if (((rhs_code == VEC_COND_EXPR || rhs_code == COND_EXPR)
+       ? !is_gimple_condexpr (rhs1) : !is_gimple_val (rhs1))
       || !is_gimple_val (rhs2)
       || !is_gimple_val (rhs3))
     {
@@ -3668,7 +3688,7 @@ verify_gimple_assign_ternary (gimple stmt)
           && !FIXED_POINT_TYPE_P (rhs1_type))
          || !useless_type_conversion_p (rhs1_type, rhs2_type)
          || !useless_type_conversion_p (lhs_type, rhs3_type)
-         || 2 * TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (lhs_type)
+         || 2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type)
          || TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type))
        {
          error ("type mismatch in widening multiply-accumulate expression");
@@ -3694,6 +3714,19 @@ verify_gimple_assign_ternary (gimple stmt)
        }
       break;
 
+    case COND_EXPR:
+    case VEC_COND_EXPR:
+      if (!useless_type_conversion_p (lhs_type, rhs2_type)
+         || !useless_type_conversion_p (lhs_type, rhs3_type))
+       {
+         error ("type mismatch in conditional expression");
+         debug_generic_expr (lhs_type);
+         debug_generic_expr (rhs2_type);
+         debug_generic_expr (rhs3_type);
+         return true;
+       }
+      break;
+
     case DOT_PROD_EXPR:
     case REALIGN_LOAD_EXPR:
       /* FIXME.  */
@@ -3810,26 +3843,10 @@ verify_gimple_assign_single (gimple stmt)
        }
       return res;
 
-    case COND_EXPR:
-      if (!is_gimple_reg (lhs)
-         || (!is_gimple_reg (TREE_OPERAND (rhs1, 0))
-             && !COMPARISON_CLASS_P (TREE_OPERAND (rhs1, 0)))
-         || (!is_gimple_reg (TREE_OPERAND (rhs1, 1))
-             && !is_gimple_min_invariant (TREE_OPERAND (rhs1, 1)))
-         || (!is_gimple_reg (TREE_OPERAND (rhs1, 2))
-             && !is_gimple_min_invariant (TREE_OPERAND (rhs1, 2))))
-       {
-         error ("invalid COND_EXPR in gimple assignment");
-         debug_generic_stmt (rhs1);
-         return true;
-       }
-      return res;
-
     case CONSTRUCTOR:
     case OBJ_TYPE_REF:
     case ASSERT_EXPR:
     case WITH_SIZE_EXPR:
-    case VEC_COND_EXPR:
       /* FIXME.  */
       return res;
 
@@ -5411,12 +5428,10 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
   int total_freq = 0, exit_freq = 0;
   gcov_type total_count = 0, exit_count = 0;
   edge exits[2], nexits[2], e;
-  gimple_stmt_iterator gsi,gsi1;
+  gimple_stmt_iterator gsi;
   gimple cond_stmt;
   edge sorig, snew;
   basic_block exit_bb;
-  basic_block iters_bb;
-  tree new_rhs;
   gimple_stmt_iterator psi;
   gimple phi;
   tree def;
@@ -5497,35 +5512,6 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
   gcc_assert (gimple_code (cond_stmt) == GIMPLE_COND);
   cond_stmt = gimple_copy (cond_stmt);
 
- /* If the block consisting of the exit condition has the latch as
-    successor, then the body of the loop is executed before
-    the exit condition is tested.  In such case, moving the
-    condition to the entry, causes that the loop will iterate
-    one less iteration (which is the wanted outcome, since we
-    peel out the last iteration).  If the body is executed after
-    the condition, moving the condition to the entry requires
-    decrementing one iteration.  */
-  if (exits[1]->dest == orig_loop->latch)
-    new_rhs = gimple_cond_rhs (cond_stmt);
-  else
-  {
-    new_rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (gimple_cond_rhs (cond_stmt)),
-                          gimple_cond_rhs (cond_stmt),
-                          build_int_cst (TREE_TYPE (gimple_cond_rhs (cond_stmt)), 1));
-
-    if (TREE_CODE (gimple_cond_rhs (cond_stmt)) == SSA_NAME)
-      {
-       iters_bb = gimple_bb (SSA_NAME_DEF_STMT (gimple_cond_rhs (cond_stmt)));
-       for (gsi1 = gsi_start_bb (iters_bb); !gsi_end_p (gsi1); gsi_next (&gsi1))
-         if (gsi_stmt (gsi1) == SSA_NAME_DEF_STMT (gimple_cond_rhs (cond_stmt)))
-           break;
-
-       new_rhs = force_gimple_operand_gsi (&gsi1, new_rhs, true,
-                                           NULL_TREE,false,GSI_CONTINUE_LINKING);
-      }
-  }
-  gimple_cond_set_rhs (cond_stmt, unshare_expr (new_rhs));
-  gimple_cond_set_lhs (cond_stmt, unshare_expr (gimple_cond_lhs (cond_stmt)));
   gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
 
   sorig = single_succ_edge (switch_bb);