https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- bool operator_addr_expr::fold_range (irange &r, tree type, const irange &lh, const irange &rh, relation_trio) const { if (empty_range_varying (r, type, lh, rh)) return true; // Return a non-null pointer of the LHS type (passed in op2). if (lh.zero_p ()) r = range_zero (type); not sure how this is called, but we can only derive this if the offset is zero as well, definitely if targetm.addr_space.zero_address_valid, but I think this is true in general. else if (!contains_zero_p (lh)) r = range_nonzero (type); and this is only true for TYPE_OVERFLOW_UNDEFINED (type), with -fwrapv-pointer we could wrap to zero. That is, it's _not_ GIMPLE undefined behavior to compute &0->bar. It looks like without -fwrapv-pointer we elide the if (!a) check, dereferencing it when dso && dso != curr. I suppose that looks reasonable with a = &dso->maj, when dso != 0 then a != 0 unless ->maj wraps.