/* __builtin_object_size (ptr, object_size_type) computation
- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>
#include "tree.h"
#include "toplev.h"
#include "diagnostic.h"
+#include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
#include "tree-flow.h"
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
{
unsigned HOST_WIDE_INT sz;
- if (!osi)
+ if (!osi || (object_size_type & 1) != 0)
sz = compute_builtin_object_size (TREE_OPERAND (pt_var, 0),
- object_size_type);
+ object_size_type & ~1);
else
{
tree var = TREE_OPERAND (pt_var, 0);
&& TREE_CODE (var) != IMAGPART_EXPR)
var = TREE_OPERAND (var, 0);
if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
- var = TREE_OPERAND (var, 0);
+ var = TREE_OPERAND (var, 0);
if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
|| ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
|| (pt_var_size
v = NULL_TREE;
break;
}
- if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
- == RECORD_TYPE)
+ while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+ != UNION_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+ != QUAL_UNION_TYPE)
+ break;
+ else
+ v = TREE_OPERAND (v, 0);
+ if (TREE_CODE (v) == COMPONENT_REF
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+ == RECORD_TYPE)
{
tree fld_chain = TREE_CHAIN (TREE_OPERAND (v, 1));
for (; fld_chain; fld_chain = TREE_CHAIN (fld_chain))
v = NULL_TREE;
break;
}
+ v = TREE_OPERAND (v, 0);
}
-
- if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
- == RECORD_TYPE)
- v = TREE_OPERAND (v, 0);
- while (v && v != pt_var && TREE_CODE (v) == COMPONENT_REF)
- if (TREE_CODE (TREE_TYPE (v)) != UNION_TYPE
- && TREE_CODE (TREE_TYPE (v)) != QUAL_UNION_TYPE)
+ while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+ != UNION_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+ != QUAL_UNION_TYPE)
break;
else
v = TREE_OPERAND (v, 0);
- if (v && v != pt_var)
+ if (v != pt_var)
v = NULL_TREE;
else
v = pt_var;
if (TREE_CHAIN (p))
arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1;
}
-
+
if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
switch (DECL_FUNCTION_CODE (callee))
{
if (arg1 < 0 || arg1 >= (int)gimple_call_num_args (call)
|| TREE_CODE (gimple_call_arg (call, arg1)) != INTEGER_CST
- || (arg2 >= 0
+ || (arg2 >= 0
&& (arg2 >= (int)gimple_call_num_args (call)
|| TREE_CODE (gimple_call_arg (call, arg2)) != INTEGER_CST)))
- return unknown[object_size_type];
+ return unknown[object_size_type];
if (arg2 >= 0)
bytes = size_binop (MULT_EXPR,
{
tree basevar = gimple_assign_rhs1 (stmt);
tree cst = gimple_assign_rhs2 (stmt);
-
+
gcc_assert (TREE_CODE (cst) == INTEGER_CST);
if (integer_zerop (cst))
result = fold_convert (size_type_node,
integer_minus_one_node);
else if (object_size_type < 4)
- result = size_zero_node;
+ result = fold_convert (size_type_node,
+ integer_zero_node);
}
}