aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authorDaniel Berlin <dberlin@dberlin.org>2005-07-01 19:45:23 +0000
committerDaniel Berlin <dberlin@gcc.gnu.org>2005-07-01 19:45:23 +0000
commitdd68d9887bc15212876eca46c54124bb2f83645c (patch)
tree803b5bdcf0e6b0550be1e719cf541b0c48e1b418 /gcc/tree-ssa-structalias.c
parent7523dc31c39c8ce458de40fca13f1b25a19dd942 (diff)
downloadgcc-dd68d9887bc15212876eca46c54124bb2f83645c.zip
gcc-dd68d9887bc15212876eca46c54124bb2f83645c.tar.gz
gcc-dd68d9887bc15212876eca46c54124bb2f83645c.tar.bz2
re PR tree-optimization/22071 (ICE in first_vi_for_offset, at tree-ssa-structalias.c:2506)
2005-06-29 Daniel Berlin <dberlin@dberlin.org> Fix PR tree-optimization/22071 * tree-ssa-structalias.c (offset_overlaps_with_access): New function. (get_constraint_for_component_ref): Use it. From-SVN: r101516
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r--gcc/tree-ssa-structalias.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 61137aa..06adb3e 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -1940,6 +1940,25 @@ bitpos_of_field (const tree fdecl)
}
+/* Return true if an access to [ACCESSPOS, ACCESSSIZE]
+ overlaps with a field at [FIELDPOS, FIELDSIZE] */
+
+static bool
+offset_overlaps_with_access (const unsigned HOST_WIDE_INT fieldpos,
+ const unsigned HOST_WIDE_INT fieldsize,
+ const unsigned HOST_WIDE_INT accesspos,
+ const unsigned HOST_WIDE_INT accesssize)
+{
+ if (fieldpos == accesspos && fieldsize == accesssize)
+ return true;
+ if (accesspos >= fieldpos && accesspos <= (fieldpos + fieldsize))
+ return true;
+ if (accesspos < fieldpos && (accesspos + accesssize > fieldpos))
+ return true;
+
+ return false;
+}
+
/* Given a COMPONENT_REF T, return the constraint_expr for it. */
static struct constraint_expr
@@ -2000,8 +2019,27 @@ get_constraint_for_component_ref (tree t)
we may have to do something cute here. */
if (result.offset < get_varinfo (result.var)->fullsize)
- result.var = first_vi_for_offset (get_varinfo (result.var),
- result.offset)->id;
+ {
+ /* It's also not true that the constraint will actually start at the
+ right offset, it may start in some padding. We only care about
+ setting the constraint to the first actual field it touches, so
+ walk to find it. */
+ varinfo_t curr;
+ for (curr = get_varinfo (result.var); curr; curr = curr->next)
+ {
+ if (offset_overlaps_with_access (curr->offset, curr->size,
+ result.offset, bitsize))
+ {
+ result.var = curr->id;
+ break;
+
+ }
+ }
+ /* assert that we found *some* field there. The user couldn't be
+ accessing *only* padding. */
+
+ gcc_assert (curr);
+ }
else
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Access to past the end of variable, ignoring\n");