diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-04-09 17:00:10 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-04-09 17:00:10 +0000 |
commit | d9745cea0edd0db7c11861860449a97e00dcb575 (patch) | |
tree | 227546b12a4334149bbdfbb52ced391d41ec4f21 /gcc/tree-ssa-ccp.c | |
parent | 1a5e0d99fe9d841c7ce6dfff72c15a7f8099e11b (diff) | |
download | gcc-d9745cea0edd0db7c11861860449a97e00dcb575.tar.gz |
* gcc.dg/tree-ssa/foldaddr-3.c: New file.
* tree-ssa-ccp (maybe_fold_offset_to_component_ref): Recurse into
multiple fields of union.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123674 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r-- | gcc/tree-ssa-ccp.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index ebf2708c18a..8e4d88ca457 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1648,6 +1648,8 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset, tree orig_type, bool base_is_ptr) { tree f, t, field_type, tail_array_field, field_offset; + tree ret; + tree new_base; if (TREE_CODE (record_type) != RECORD_TYPE && TREE_CODE (record_type) != UNION_TYPE @@ -1719,8 +1721,20 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset, /* If we matched, then set offset to the displacement into this field. */ - offset = t; - goto found; + if (base_is_ptr) + new_base = build1 (INDIRECT_REF, record_type, base); + else + new_base = base; + new_base = build3 (COMPONENT_REF, field_type, new_base, f, NULL_TREE); + + /* Recurse to possibly find the match. */ + ret = maybe_fold_offset_to_array_ref (new_base, t, orig_type); + if (ret) + return ret; + ret = maybe_fold_offset_to_component_ref (field_type, new_base, t, + orig_type, false); + if (ret) + return ret; } if (!tail_array_field) @@ -1730,7 +1744,6 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset, field_type = TREE_TYPE (f); offset = int_const_binop (MINUS_EXPR, offset, byte_position (f), 1); - found: /* If we get here, we've got an aggregate field, and a possibly nonzero offset into them. Recurse and hope for a valid match. */ if (base_is_ptr) |