diff options
author | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-22 13:39:18 +0000 |
---|---|---|
committer | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-22 13:39:18 +0000 |
commit | e911adadf279416c4acaa4479b60c0ad020159db (patch) | |
tree | a90ff2874706640af3b68570fabd2d4bcd045798 /gcc/tree-ssa-structalias.c | |
parent | e600139e603ff83608932fc41cbde0226f95cf36 (diff) | |
download | gcc-e911adadf279416c4acaa4479b60c0ad020159db.tar.gz |
* tree-ssa-alias.c (count_ptr_derefs): Do not consider
&PTR->FLD a dereference of PTR.
* tree-ssa-structalias.c (update_alias_info): Consider &PTR->FLD
a potential dereference of PTR.
testsuite/ChangeLog
* gcc.dg/tree-ssa/20050719-1.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102283 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r-- | gcc/tree-ssa-structalias.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 867c6a76364..2a10a8d3d11 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -2555,7 +2555,7 @@ update_alias_info (tree stmt, struct alias_info *ai) tree op, var; var_ann_t v_ann; struct ptr_info_def *pi; - bool is_store; + bool is_store, is_potential_deref; unsigned num_uses, num_derefs; op = USE_FROM_PTR (use_p); @@ -2612,7 +2612,42 @@ update_alias_info (tree stmt, struct alias_info *ai) is an escape point, whether OP escapes. */ count_uses_and_derefs (op, stmt, &num_uses, &num_derefs, &is_store); - if (num_derefs > 0) + /* Handle a corner case involving address expressions of the + form '&PTR->FLD'. The problem with these expressions is that + they do not represent a dereference of PTR. However, if some + other transformation propagates them into an INDIRECT_REF + expression, we end up with '*(&PTR->FLD)' which is folded + into 'PTR->FLD'. + + So, if the original code had no other dereferences of PTR, + the aliaser will not create memory tags for it, and when + &PTR->FLD gets propagated to INDIRECT_REF expressions, the + memory operations will receive no V_MAY_DEF/VUSE operands. + + One solution would be to have count_uses_and_derefs consider + &PTR->FLD a dereference of PTR. But that is wrong, since it + is not really a dereference but an offset calculation. + + What we do here is to recognize these special ADDR_EXPR + nodes. Since these expressions are never GIMPLE values (they + are not GIMPLE invariants), they can only appear on the RHS + of an assignment and their base address is always an + INDIRECT_REF expression. */ + is_potential_deref = false; + if (TREE_CODE (stmt) == MODIFY_EXPR + && TREE_CODE (TREE_OPERAND (stmt, 1)) == ADDR_EXPR + && !is_gimple_val (TREE_OPERAND (stmt, 1))) + { + /* If the RHS if of the form &PTR->FLD and PTR == OP, then + this represents a potential dereference of PTR. */ + tree rhs = TREE_OPERAND (stmt, 1); + tree base = get_base_address (TREE_OPERAND (rhs, 0)); + if (TREE_CODE (base) == INDIRECT_REF + && TREE_OPERAND (base, 0) == op) + is_potential_deref = true; + } + + if (num_derefs > 0 || is_potential_deref) { /* Mark OP as dereferenced. In a subsequent pass, dereferenced pointers that point to a set of |