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);