aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr22071.C14
-rw-r--r--gcc/tree-ssa-structalias.c42
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");