On Mon, Aug 20, 2018 at 1:05 PM Marc Glisse <marc.gli...@inria.fr> wrote: > > On Mon, 20 Aug 2018, Richard Biener wrote: > > > On Mon, Aug 20, 2018 at 10:53 AM Andreas Schwab <sch...@suse.de> wrote: > >> > >> On Aug 20 2018, Richard Biener <richard.guent...@gmail.com> wrote: > >> > >>> Btw, I can't find wording in the standards that nullptr + 1 is > >>> invoking undefined behavior, > >>> that is, that pointer arithmetic is only allowed on pointers pointing > >>> to a valid object. > >>> Any specific pointers? > >> > >> All of 5.7 talks about pointers pointing to objects (except when adding > >> 0). > > > > Thanks all for the response. Working on a patch introducing infrastructure > > for this right now but implementing this we'd need to make sure to not > > hoist pointer arithmetic into blocks that might otherwise not be executed. > > Like > > > > if (p != 0) > > { > > q = p + 1; > > foo (q); > > } > > > > may not be optimized to > > > > q = p + 1; > > if (p != 0) > > foo (q); > > > > because then we'd elide the p != 0 check. I'm implementing the > > infrastructure > > to assume y != 0 after a stmt like z = x / y; where we'd already avoid > > such hoisting > > because it may trap at runtime. > > > > Similar "issues" would be exposed when hoisting undefined overflow > > stmts and we'd > > derive ranges for their operands. > > > > So I'm not entirely sure it's worth the likely trouble. > > The opposite direction may be both easier and safer, even if it won't > handle everything: > > P p+ N is nonnull if P or N is known to be nonnull > (and something similar for &p->field and others)
But we already do that. else if (code == POINTER_PLUS_EXPR) { /* For pointer types, we are really only interested in asserting whether the expression evaluates to non-NULL. */ if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1)) set_value_range_to_nonnull (vr, expr_type); else if (range_is_null (&vr0) && range_is_null (&vr1)) set_value_range_to_null (vr, expr_type); else set_value_range_to_varying (vr); } Ah, range_is_nonnull (&vr1) is only matching ~[0,0]. We'd probably want VR_RANGE && !range_includes_zero_p here. That range_is_nonnull is probably never true due to canonicalization. Richard. > > -- > Marc Glisse