+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
--- /dev/null
+/* { 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;
}
+/* 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
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");