diff options
author | Daniel Berlin <dberlin@dberlin.org> | 2005-06-21 00:59:17 +0000 |
---|---|---|
committer | Daniel Berlin <dberlin@gcc.gnu.org> | 2005-06-21 00:59:17 +0000 |
commit | a5eadacc354407939f4bbf55bd44d750e3554344 (patch) | |
tree | 441f3bfca76fbff3165789a7e384227c2ba626ac | |
parent | 83fbfe42c25f312d47f30be37bcb957c2b7258cf (diff) | |
download | gcc-a5eadacc354407939f4bbf55bd44d750e3554344.zip gcc-a5eadacc354407939f4bbf55bd44d750e3554344.tar.gz gcc-a5eadacc354407939f4bbf55bd44d750e3554344.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/c-typeck.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pta-1.c | 31 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 29 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 64 |
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 (); |