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

Reply via email to