aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/c-typeck.c1
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pta-1.c31
-rw-r--r--gcc/tree-ssa-alias.c29
-rw-r--r--gcc/tree-ssa-structalias.c64
5 files changed, 121 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 06dc476..0113201 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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*.
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 988d958..7f462c4 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -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);
diff --git a/gcc/testsuite/gcc.c-torture/compile/pta-1.c b/gcc/testsuite/gcc.c-torture/compile/pta-1.c
new file mode 100644
index 0000000..515e5ff
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pta-1.c
@@ -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;
+}
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 3098549..04125ca 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -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:
{
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 5ca2a5c..4aeda11 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -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)
@@ -2362,14 +2383,12 @@ do_structure_copy (tree lhsop, tree rhsop)
tree rhsdecl = get_varinfo (rhs.var)->decl;
tree pointertype = TREE_TYPE (rhsdecl);
tree pointedtotype = TREE_TYPE (pointertype);
- tree tmpvar;
+ 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);
}
}
}
@@ -2723,7 +2742,7 @@ create_variable_info_for (tree decl, const char *name)
vi->offset = 0;
vi->has_union = hasunion;
if (!TYPE_SIZE (decltype)
- || TREE_CODE (TYPE_SIZE (decltype)) != INTEGER_CST
+ || TREE_CODE (TYPE_SIZE (decltype)) != INTEGER_CST
|| TREE_CODE (decltype) == ARRAY_TYPE
|| TREE_CODE (decltype) == UNION_TYPE
|| TREE_CODE (decltype) == QUAL_UNION_TYPE)
@@ -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));
}
@@ -3101,7 +3130,6 @@ static void
create_alias_vars (void)
{
basic_block bb;
-
init_alias_vars ();