https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111009
--- Comment #4 from Andrew Macleod <amacleod at redhat dot com> --- (In reply to Richard Biener from comment #3) > 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. Range-ops won't see anything like &dso->maj.. it sees rangers and nothing else. it just gets the result of that expression determined by someone else. . so if it see [0,0] for the range, that means &dso->maj has been determined to be 0. When folding, addressof has some funky mechanics, and it symbolically processes the trees in gimple-range-fold.cc in fold_using_range::range_of_address I think it takes care of all the funky things you mention. I also notice in the earlier comment where we set _13 to 0... the code you quoted where _13 was recomputed by ranger. it ends with GORI TRUE : (797) recomputation (_13) [irange] _Bool [1, 1] The result was [1,1] as far as ranger was concerned o the edge from 3->16 so that prop0bably isn't how gimple fold determined it was zero. Is there still an issue here?