c-typeck.c (build_function_call): Set fundecl = function again.
2005-06-20 Daniel Berlin <dberlin@dberlin.org> * c-typeck.c (build_function_call): Set fundecl = function again. * tree-ssa-alias.c (find_used_portions): Address taking causes the entire variable to be used. * tree-ssa-structalias.c (do_structure_copy): Fix handling of unknown size variables, and structure copies from addressof operations. Simplify how we do *a = *b type structure copies. (init_base_vars): Add ANYTHING = &ANYTHING constraint the right way. READONLY's address is not taken by default. INTEGER dereference should point to anything. (create_variable_info_for): It's okay for the first field to not start at 0. From-SVN: r101227
This commit is contained in:
parent
83fbfe42c2
commit
a5eadacc35
@ -1,3 +1,17 @@
|
||||
2005-06-20 Daniel Berlin <dberlin@dberlin.org>
|
||||
|
||||
* c-typeck.c (build_function_call): Set fundecl = function again.
|
||||
* tree-ssa-alias.c (find_used_portions): Address taking causes the
|
||||
entire variable to be used.
|
||||
* tree-ssa-structalias.c (do_structure_copy): Fix handling of
|
||||
unknown size variables, and structure copies from addressof
|
||||
operations. Simplify how we do *a = *b type structure copies.
|
||||
(init_base_vars): Add ANYTHING = &ANYTHING constraint the right
|
||||
way. READONLY's address is not taken by default.
|
||||
INTEGER dereference should point to anything.
|
||||
(create_variable_info_for): It's okay for the first field to not start
|
||||
at 0.
|
||||
|
||||
2005-06-20 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
config/sh/linux.h (FUNCTION_PROFILER): Constify a char*.
|
||||
|
@ -1990,6 +1990,7 @@ build_function_call (tree function, tree params)
|
||||
return tem;
|
||||
|
||||
name = DECL_NAME (function);
|
||||
fundecl = function;
|
||||
}
|
||||
function = default_function_array_conversion (function);
|
||||
|
||||
|
31
gcc/testsuite/gcc.c-torture/compile/pta-1.c
Normal file
31
gcc/testsuite/gcc.c-torture/compile/pta-1.c
Normal file
@ -0,0 +1,31 @@
|
||||
typedef struct JSObject JSObject;
|
||||
typedef struct JSObjectMap *(*JSNewObjectMapOp) (JSObject *obj);
|
||||
typedef JSObject *(*JSGetMethodOp) (JSObject *obj);
|
||||
struct JSObjectOps {
|
||||
JSNewObjectMapOp newObjectMap;
|
||||
};
|
||||
struct JSXMLObjectOps {
|
||||
struct JSObjectOps base;
|
||||
JSGetMethodOp getMethod;
|
||||
};
|
||||
struct JSObjectMap {
|
||||
struct JSObjectOps *ops;
|
||||
};
|
||||
struct JSObject {
|
||||
struct JSObjectMap *map;
|
||||
};
|
||||
|
||||
struct JSXMLObjectOps js_XMLObjectOps;
|
||||
|
||||
|
||||
/* We need to create SFT's for the entire structure when this address is taken,
|
||||
not just the part in the component reference itself. */
|
||||
JSObject *JS_GetMethod(JSObject *obj)
|
||||
{
|
||||
if (obj->map->ops == &js_XMLObjectOps.base) {
|
||||
struct JSXMLObjectOps *ops;
|
||||
ops = (struct JSXMLObjectOps *) obj->map->ops;
|
||||
obj = ops->getMethod(obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
@ -3119,6 +3119,35 @@ find_used_portions (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
|
||||
}
|
||||
}
|
||||
break;
|
||||
/* This is here to make sure we mark the entire base variable as used
|
||||
when you take its address. Because our used portion analysis is
|
||||
simple, we aren't looking at casts or pointer arithmetic to see what
|
||||
happens when you take the address. */
|
||||
case ADDR_EXPR:
|
||||
{
|
||||
tree var = get_base_address (TREE_OPERAND (*tp, 0));
|
||||
|
||||
if (var
|
||||
&& DECL_P (var)
|
||||
&& DECL_SIZE (var)
|
||||
&& var_can_have_subvars (var)
|
||||
&& TREE_CODE (DECL_SIZE (var)) == INTEGER_CST)
|
||||
{
|
||||
used_part_t up;
|
||||
size_t uid = var_ann (var)->uid;
|
||||
|
||||
up = get_or_create_used_part_for (uid);
|
||||
|
||||
up->minused = 0;
|
||||
up->maxused = TREE_INT_CST_LOW (DECL_SIZE (var));
|
||||
up->implicit_uses = true;
|
||||
|
||||
used_portions[uid] = up;
|
||||
*walk_subtrees = 0;
|
||||
return NULL_TREE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VAR_DECL:
|
||||
case PARM_DECL:
|
||||
{
|
||||
|
@ -2210,8 +2210,7 @@ do_simple_structure_copy (const struct constraint_expr lhs,
|
||||
const unsigned HOST_WIDE_INT size)
|
||||
{
|
||||
varinfo_t p = get_varinfo (lhs.var);
|
||||
unsigned HOST_WIDE_INT pstart,last;
|
||||
|
||||
unsigned HOST_WIDE_INT pstart, last;
|
||||
pstart = p->offset;
|
||||
last = p->offset + size;
|
||||
for (; p && p->offset < last; p = p->next)
|
||||
@ -2321,8 +2320,6 @@ do_structure_copy (tree lhsop, tree rhsop)
|
||||
unsigned HOST_WIDE_INT lhssize;
|
||||
unsigned HOST_WIDE_INT rhssize;
|
||||
|
||||
lhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhsop)));
|
||||
rhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (rhsop)));
|
||||
lhs = get_constraint_for (lhsop);
|
||||
rhs = get_constraint_for (rhsop);
|
||||
|
||||
@ -2334,8 +2331,18 @@ do_structure_copy (tree lhsop, tree rhsop)
|
||||
rhs = tmp;
|
||||
}
|
||||
|
||||
/* If the RHS is a special var, set all the LHS fields to that
|
||||
special var. */
|
||||
/* This is fairly conservative for the RHS == ADDRESSOF case, in that it's
|
||||
possible it's something we could handle. However, most cases falling
|
||||
into this are dealing with transparent unions, which are slightly
|
||||
weird. */
|
||||
if (rhs.type == ADDRESSOF && rhs.var > integer_id)
|
||||
{
|
||||
rhs.type = ADDRESSOF;
|
||||
rhs.var = anything_id;
|
||||
}
|
||||
|
||||
/* If the RHS is a special var, or an addressof, set all the LHS fields to
|
||||
that special var. */
|
||||
if (rhs.var <= integer_id)
|
||||
{
|
||||
for (p = get_varinfo (lhs.var); p; p = p->next)
|
||||
@ -2351,6 +2358,20 @@ do_structure_copy (tree lhsop, tree rhsop)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The size only really matters insofar as we don't set more or less of
|
||||
the variable. If we hit an unknown size var, the size should be the
|
||||
whole darn thing. */
|
||||
if (get_varinfo (rhs.var)->is_unknown_size_var)
|
||||
rhssize = ~0;
|
||||
else
|
||||
rhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (rhsop)));
|
||||
|
||||
if (get_varinfo (lhs.var)->is_unknown_size_var)
|
||||
lhssize = ~0;
|
||||
else
|
||||
lhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhsop)));
|
||||
|
||||
|
||||
if (rhs.type == SCALAR && lhs.type == SCALAR)
|
||||
do_simple_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
|
||||
else if (lhs.type != DEREF && rhs.type == DEREF)
|
||||
@ -2363,13 +2384,11 @@ do_structure_copy (tree lhsop, tree rhsop)
|
||||
tree pointertype = TREE_TYPE (rhsdecl);
|
||||
tree pointedtotype = TREE_TYPE (pointertype);
|
||||
tree tmpvar;
|
||||
|
||||
gcc_assert (rhs.type == DEREF && lhs.type == DEREF);
|
||||
tmpvar = create_tmp_var_raw (pointedtotype, "structcopydereftmp");
|
||||
lhs = get_constraint_for (tmpvar);
|
||||
do_rhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
|
||||
rhs = lhs;
|
||||
lhs = get_constraint_for (lhsop);
|
||||
do_lhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
|
||||
do_structure_copy (tmpvar, rhsop);
|
||||
do_structure_copy (lhsop, tmpvar);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2786,7 +2805,6 @@ create_variable_info_for (tree decl, const char *name)
|
||||
}
|
||||
|
||||
field = fo->field;
|
||||
gcc_assert (bitpos_of_field (field) == 0);
|
||||
vi->size = TREE_INT_CST_LOW (DECL_SIZE (field));
|
||||
for (i = 1; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
|
||||
{
|
||||
@ -3049,8 +3067,10 @@ init_base_vars (void)
|
||||
rhs.var = anything_id;
|
||||
rhs.offset = 0;
|
||||
var_anything->address_taken = true;
|
||||
process_constraint (new_constraint (lhs, rhs));
|
||||
|
||||
/* This specifically does not use process_constraint because
|
||||
process_constraint ignores all anything = anything constraints, since all
|
||||
but this one are redundant. */
|
||||
VEC_safe_push (constraint_t, gc, constraints, new_constraint (lhs, rhs));
|
||||
|
||||
/* Create the READONLY variable, used to represent that a variable
|
||||
points to readonly memory. */
|
||||
@ -3075,7 +3095,6 @@ init_base_vars (void)
|
||||
rhs.type = ADDRESSOF;
|
||||
rhs.var = anything_id;
|
||||
rhs.offset = 0;
|
||||
var_readonly->address_taken = true;
|
||||
|
||||
process_constraint (new_constraint (lhs, rhs));
|
||||
|
||||
@ -3091,6 +3110,16 @@ init_base_vars (void)
|
||||
var_integer->next = NULL;
|
||||
integer_id = 3;
|
||||
VEC_safe_push (varinfo_t, gc, varmap, var_integer);
|
||||
|
||||
/* *INTEGER = ANYTHING, because we don't know where a dereference of a random
|
||||
integer will point to. */
|
||||
lhs.type = SCALAR;
|
||||
lhs.var = integer_id;
|
||||
lhs.offset = 0;
|
||||
rhs.type = ADDRESSOF;
|
||||
rhs.var = anything_id;
|
||||
rhs.offset = 0;
|
||||
process_constraint (new_constraint (lhs, rhs));
|
||||
}
|
||||
|
||||
|
||||
@ -3102,7 +3131,6 @@ create_alias_vars (void)
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
|
||||
init_alias_vars ();
|
||||
|
||||
constraint_pool = create_alloc_pool ("Constraint pool",
|
||||
|
Loading…
Reference in New Issue
Block a user