OSDN Git Service

* cfgcleanup.c (try_head_merge_bb): If get_condition returns
[pf3gnuchains/gcc-fork.git] / gcc / tree-object-size.c
index 092348b..b176758 100644 (file)
@@ -1,5 +1,5 @@
 /* __builtin_object_size (ptr, object_size_type) computation
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Jakub Jelinek <jakub@redhat.com>
 
@@ -25,7 +25,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "diagnostic-core.h"
-#include "toplev.h"
 #include "tree-pretty-print.h"
 #include "gimple-pretty-print.h"
 #include "tree-flow.h"
@@ -54,7 +53,7 @@ static void expr_object_size (struct object_size_info *, tree, tree);
 static bool merge_object_sizes (struct object_size_info *, tree, tree,
                                unsigned HOST_WIDE_INT);
 static bool plus_stmt_object_size (struct object_size_info *, tree, gimple);
-static bool cond_expr_object_size (struct object_size_info *, tree, tree);
+static bool cond_expr_object_size (struct object_size_info *, tree, gimple);
 static unsigned int compute_object_sizes (void);
 static void init_offset_limit (void);
 static void check_for_plus_in_loops (struct object_size_info *, tree);
@@ -144,7 +143,7 @@ compute_object_offset (const_tree expr, const_tree var)
 
     case MEM_REF:
       gcc_assert (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR);
-      return TREE_OPERAND (expr, 1);
+      return double_int_to_tree (sizetype, mem_ref_offset (expr));
 
     default:
       return error_mark_node;
@@ -206,6 +205,12 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
        pt_var_size = size_int (sz);
     }
   else if (pt_var
+          && DECL_P (pt_var)
+          && host_integerp (DECL_SIZE_UNIT (pt_var), 1)
+          && (unsigned HOST_WIDE_INT)
+               tree_low_cst (DECL_SIZE_UNIT (pt_var), 1) < offset_limit)
+    pt_var_size = DECL_SIZE_UNIT (pt_var);
+  else if (pt_var
           && (SSA_VAR_P (pt_var) || TREE_CODE (pt_var) == STRING_CST)
           && TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
           && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
@@ -349,8 +354,6 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
          tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0), pt_var);
          if (bytes2 != error_mark_node)
            {
-             bytes2 = size_binop (PLUS_EXPR, bytes2,
-                                  TREE_OPERAND (pt_var, 1));
              if (TREE_CODE (bytes2) == INTEGER_CST
                  && tree_int_cst_lt (pt_var_size, bytes2))
                bytes2 = size_zero_node;
@@ -461,6 +464,7 @@ pass_through_call (const_gimple call)
       case BUILT_IN_STRNCPY_CHK:
       case BUILT_IN_STRCAT_CHK:
       case BUILT_IN_STRNCAT_CHK:
+      case BUILT_IN_ASSUME_ALIGNED:
        if (gimple_call_num_args (call) >= 1)
          return gimple_call_arg (call, 0);
        break;
@@ -823,25 +827,25 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple stmt)
 }
 
 
-/* Compute object_sizes for VAR, defined to VALUE, which is
+/* Compute object_sizes for VAR, defined at STMT, which is
    a COND_EXPR.  Return true if the object size might need reexamination
    later.  */
 
 static bool
-cond_expr_object_size (struct object_size_info *osi, tree var, tree value)
+cond_expr_object_size (struct object_size_info *osi, tree var, gimple stmt)
 {
   tree then_, else_;
   int object_size_type = osi->object_size_type;
   unsigned int varno = SSA_NAME_VERSION (var);
   bool reexamine = false;
 
-  gcc_assert (TREE_CODE (value) == COND_EXPR);
+  gcc_assert (gimple_assign_rhs_code (stmt) == COND_EXPR);
 
   if (object_sizes[object_size_type][varno] == unknown[object_size_type])
     return false;
 
-  then_ = COND_EXPR_THEN (value);
-  else_ = COND_EXPR_ELSE (value);
+  then_ = gimple_assign_rhs2 (stmt);
+  else_ = gimple_assign_rhs3 (stmt);
 
   if (TREE_CODE (then_) == SSA_NAME)
     reexamine |= merge_object_sizes (osi, var, then_, 0);
@@ -928,14 +932,14 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
            || (gimple_assign_rhs_code (stmt) == ADDR_EXPR
                && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF))
           reexamine = plus_stmt_object_size (osi, var, stmt);
+       else if (gimple_assign_rhs_code (stmt) == COND_EXPR)
+         reexamine = cond_expr_object_size (osi, var, stmt);
         else if (gimple_assign_single_p (stmt)
                  || gimple_assign_unary_nop_p (stmt))
           {
             if (TREE_CODE (rhs) == SSA_NAME
                 && POINTER_TYPE_P (TREE_TYPE (rhs)))
               reexamine = merge_object_sizes (osi, var, rhs, 0);
-            else if (TREE_CODE (rhs) == COND_EXPR)
-              reexamine = cond_expr_object_size (osi, var, rhs);
             else
               expr_object_size (osi, var, rhs);
           }
@@ -952,8 +956,6 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
             if (TREE_CODE (arg) == SSA_NAME
                 && POINTER_TYPE_P (TREE_TYPE (arg)))
               reexamine = merge_object_sizes (osi, var, arg, 0);
-            else if (TREE_CODE (arg) == COND_EXPR)
-              reexamine = cond_expr_object_size (osi, var, arg);
             else
               expr_object_size (osi, var, arg);
           }
@@ -1279,6 +1281,6 @@ struct gimple_opt_pass pass_object_sizes =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_ssa     /* todo_flags_finish */
+  TODO_verify_ssa                      /* todo_flags_finish */
  }
 };