summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-22 13:39:18 +0000
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-22 13:39:18 +0000
commite911adadf279416c4acaa4479b60c0ad020159db (patch)
treea90ff2874706640af3b68570fabd2d4bcd045798 /gcc/tree-ssa-structalias.c
parente600139e603ff83608932fc41cbde0226f95cf36 (diff)
downloadgcc-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.c39
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