From dd68d9887bc15212876eca46c54124bb2f83645c Mon Sep 17 00:00:00 2001 From: Daniel Berlin Date: Fri, 1 Jul 2005 19:45:23 +0000 Subject: re PR tree-optimization/22071 (ICE in first_vi_for_offset, at tree-ssa-structalias.c:2506) 2005-06-29 Daniel Berlin 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 --- gcc/ChangeLog | 8 +++++++ gcc/testsuite/g++.dg/tree-ssa/pr22071.C | 14 +++++++++++ gcc/tree-ssa-structalias.c | 42 +++++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr22071.C 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 + + 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 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"); -- cgit v1.1