/* __builtin_object_size (ptr, object_size_type) computation
- Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
static unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 };
-static tree compute_object_offset (tree, tree);
-static unsigned HOST_WIDE_INT addr_object_size (tree, int);
-static unsigned HOST_WIDE_INT alloc_object_size (tree, int);
-static tree pass_through_call (tree);
+static tree compute_object_offset (const_tree, const_tree);
+static unsigned HOST_WIDE_INT addr_object_size (const_tree, int);
+static unsigned HOST_WIDE_INT alloc_object_size (const_tree, int);
+static tree pass_through_call (const_tree);
static void collect_object_sizes_for (struct object_size_info *, tree);
static void expr_object_size (struct object_size_info *, tree, tree);
static bool merge_object_sizes (struct object_size_info *, tree, tree,
if unknown. */
static tree
-compute_object_offset (tree expr, tree var)
+compute_object_offset (const_tree expr, const_tree var)
{
enum tree_code code = PLUS_EXPR;
tree base, off, t;
If unknown, return unknown[object_size_type]. */
static unsigned HOST_WIDE_INT
-addr_object_size (tree ptr, int object_size_type)
+addr_object_size (const_tree ptr, int object_size_type)
{
tree pt_var;
unknown[object_size_type]. */
static unsigned HOST_WIDE_INT
-alloc_object_size (tree call, int object_size_type)
+alloc_object_size (const_tree call, int object_size_type)
{
tree callee, bytes = NULL_TREE;
tree alloc_size;
Otherwise return NULL. */
static tree
-pass_through_call (tree call)
+pass_through_call (const_tree call)
{
tree callee = get_callee_fndecl (call);
/* Compute object_sizes for PTR, defined to VALUE, which is
- a PLUS_EXPR. Return true if the object size might need reexamination
+ a POINTER_PLUS_EXPR. Return true if the object size might need reexamination
later. */
static bool
{
tree op0 = TREE_OPERAND (value, 0);
tree op1 = TREE_OPERAND (value, 1);
- bool ptr1_p = POINTER_TYPE_P (TREE_TYPE (op0))
- && TREE_CODE (op0) != INTEGER_CST;
- bool ptr2_p = POINTER_TYPE_P (TREE_TYPE (op1))
- && TREE_CODE (op1) != INTEGER_CST;
int object_size_type = osi->object_size_type;
unsigned int varno = SSA_NAME_VERSION (var);
unsigned HOST_WIDE_INT bytes;
- gcc_assert (TREE_CODE (value) == PLUS_EXPR);
+ gcc_assert (TREE_CODE (value) == POINTER_PLUS_EXPR);
if (object_sizes[object_size_type][varno] == unknown[object_size_type])
return false;
- /* Swap operands if needed. */
- if (ptr2_p && !ptr1_p)
- {
- tree tem = op0;
- op0 = op1;
- op1 = tem;
- ptr1_p = true;
- ptr2_p = false;
- }
-
/* Handle PTR + OFFSET here. */
- if (ptr1_p
- && !ptr2_p
- && TREE_CODE (op1) == INTEGER_CST
+ if (TREE_CODE (op1) == INTEGER_CST
&& (TREE_CODE (op0) == SSA_NAME
|| TREE_CODE (op0) == ADDR_EXPR))
{
OSI->object_size_type).
For allocation CALL_EXPR like malloc or calloc object size is the size
of the allocation.
- For pointer PLUS_EXPR where second operand is a constant integer,
+ For POINTER_PLUS_EXPR where second operand is a constant integer,
object size is object size of the first operand minus the constant.
If the constant is bigger than the number of remaining bytes until the
end of the object, object size is 0, but if it is instead a pointer
&& POINTER_TYPE_P (TREE_TYPE (rhs)))
reexamine = merge_object_sizes (osi, var, rhs, 0);
- else if (TREE_CODE (rhs) == PLUS_EXPR)
+ else if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
reexamine = plus_expr_object_size (osi, var, rhs);
else if (TREE_CODE (rhs) == COND_EXPR)
if (TREE_CODE (rhs) == SSA_NAME)
check_for_plus_in_loops_1 (osi, rhs, depth);
- else if (TREE_CODE (rhs) == PLUS_EXPR)
+ else if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
{
tree op0 = TREE_OPERAND (rhs, 0);
tree op1 = TREE_OPERAND (rhs, 1);
tree cst, basevar;
- if (TREE_CODE (op0) == SSA_NAME)
- {
- basevar = op0;
- cst = op1;
- }
- else
- {
- basevar = op1;
- cst = op0;
- gcc_assert (TREE_CODE (basevar) == SSA_NAME);
- }
+ basevar = op0;
+ cst = op1;
gcc_assert (TREE_CODE (cst) == INTEGER_CST);
check_for_plus_in_loops_1 (osi, basevar,
rhs = arg;
}
- if (TREE_CODE (rhs) == PLUS_EXPR)
+ if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
{
tree op0 = TREE_OPERAND (rhs, 0);
tree op1 = TREE_OPERAND (rhs, 1);
tree cst, basevar;
- if (TREE_CODE (op0) == SSA_NAME)
- {
- basevar = op0;
- cst = op1;
- }
- else
- {
- basevar = op1;
- cst = op0;
- gcc_assert (TREE_CODE (basevar) == SSA_NAME);
- }
+ basevar = op0;
+ cst = op1;
gcc_assert (TREE_CODE (cst) == INTEGER_CST);
if (integer_zerop (cst))