/* __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>
#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"
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);
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;
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)
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;
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;
}
-/* 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);
|| (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);
}
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);
}
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 */
}
};