diff options
author | Daniel Berlin <dberlin@dberlin.org> | 2005-07-01 19:45:23 +0000 |
---|---|---|
committer | Daniel Berlin <dberlin@gcc.gnu.org> | 2005-07-01 19:45:23 +0000 |
commit | dd68d9887bc15212876eca46c54124bb2f83645c (patch) | |
tree | 803b5bdcf0e6b0550be1e719cf541b0c48e1b418 /gcc | |
parent | 7523dc31c39c8ce458de40fca13f1b25a19dd942 (diff) | |
download | gcc-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')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/pr22071.C | 14 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 42 |
3 files changed, 62 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 37b484d..70be419 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +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. + 2005-07-01 Andrew Pinski <pinskia@physics.uc.edu> PR other/22264 diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22071.C b/gcc/testsuite/g++.dg/tree-ssa/pr22071.C new file mode 100644 index 0000000..719aed3 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr22071.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* This code ends up taking the address of part of the structure that is padding, + and because there is no real field there, the structure alias analyzer would + abort. */ +struct empty_class {}; +struct class1 : empty_class +{ + class1() {} + empty_class value_; +}; +struct lambda : class1 { }; +lambda _1; 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"); |