https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #32 from Richard Biener <rguenth at gcc dot gnu.org> ---
Hmm, or rather the logic is fine, there's simply no field at that offset in the
set of RHS constraints.  There's the missing field

$21 = {id = 30, is_artificial_var = 0, is_special_var = 0, 
  is_unknown_size_var = 0, is_full_var = 0, is_heap_var = 0, is_reg_var = 0, 
  may_have_pointers = 1, only_restrict_pointers = 0, is_restrict_var = 0, 
  is_global_var = 0, is_ipa_escape_point = 0, is_fn_info = 0, 
  address_taken = 0, ruid = 0, next = 31, head = 27, offset = 320, size = 64, 
  fullsize = 448, shadow_var_uid = 0, name = 0x7fffee90d3e0 "tok2.320+64", 
  decl = <var_decl 0x7fffefa8fab0 tok2>, solution = 0x586ee50, 
  oldsolution = 0x0}

and the issue is in get_constraint_for_1 which doesn't take into account
the case where the offset doesn't align with the first field that is
accessed.

diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc
index deca44ae0bf..0215243d5be 100644
--- a/gcc/tree-ssa-structalias.cc
+++ b/gcc/tree-ssa-structalias.cc
@@ -3690,7 +3690,10 @@ get_constraint_for_1 (tree t, vec<ce_s> *results, bool
address_p,
                    size = -1;
                  for (; curr; curr = vi_next (curr))
                    {
-                     if (curr->offset - vi->offset < size)
+                     /* The start of the access might happen anywhere
+                        within vi, so conservatively assume it was
+                        at its end.  */
+                     if (curr->offset - (vi->offset + vi->size - 1) < size)
                        {
                          cs.var = curr->id;
                          results->safe_push (cs);

Reply via email to