On Fri, Jul 1, 2016 at 3:10 PM, Manish Goregaokar <man...@mozilla.com> wrote: > Added a test:
Ok if this passed bootstrap/regtest. Richard. > gcc/ChangeLog: > PR c/71699 > * fold-const.c (tree_binary_nonzero_warnv_p): Allow > pointer addition to also be considered nonzero. > > gcc/testsuite/ChangeLog: > PR c/71699 > * c-c++-common/pointer-addition-nonnull.c: New test for > pointer addition. > --- > gcc/fold-const.c | 3 +++ > .../c-c++-common/pointer-addition-nonnull.c | 21 > +++++++++++++++++++++ > 2 files changed, 24 insertions(+) > create mode 100644 gcc/testsuite/c-c++-common/pointer-addition-nonnull.c > > diff --git a/gcc/fold-const.c b/gcc/fold-const.c > index 3b9500d..0d82018 100644 > --- a/gcc/fold-const.c > +++ b/gcc/fold-const.c > @@ -13199,6 +13199,9 @@ tree_binary_nonzero_warnv_p (enum tree_code code, > switch (code) > { > case POINTER_PLUS_EXPR: > + return flag_delete_null_pointer_checks > + && (tree_expr_nonzero_warnv_p (op0, strict_overflow_p) > + || tree_expr_nonzero_warnv_p (op1, strict_overflow_p)); > case PLUS_EXPR: > if (ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_UNDEFINED (type)) > { > diff --git a/gcc/testsuite/c-c++-common/pointer-addition-nonnull.c > b/gcc/testsuite/c-c++-common/pointer-addition-nonnull.c > new file mode 100644 > index 0000000..10bc04c > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/pointer-addition-nonnull.c > @@ -0,0 +1,21 @@ > +/* { dg-options "-c -O2 -Wall" } */ > + > +char *xstrdup (const char *) __attribute__ ((__returns_nonnull__)); > + > +#define PREFIX "some " > + > +int > +main () > +{ > + char *saveptr; > + char *name = xstrdup (PREFIX "name"); > + > + char *tail = name + sizeof (PREFIX) - 1; > + > + if (tail == 0) > + tail = saveptr; > + while (*tail == ' ') > + ++tail; > + > + return 0; > +} > \ No newline at end of file > -- > 2.8.3 > > -Manish > > > On Fri, Jul 1, 2016 at 1:40 PM, Richard Biener > <richard.guent...@gmail.com> wrote: >> On Thu, Jun 30, 2016 at 5:14 PM, Marc Glisse <marc.gli...@inria.fr> wrote: >>> On Thu, 30 Jun 2016, Richard Biener wrote: >>> >>>> points-to analysis already has the constraint that POINTER_PLUS_EXPR >>>> cannot leave the object op0 points to. Of course currently nothing uses >>>> the >>>> fact whether points-to computes pointed-to as nothing (aka NULL) - so the >>>> argument may be moot. >>>> >>>> Anyway, one of my points to the original patch was that POINTER_PLUS_EXPR >>>> handling should be clearly separate from PLUS_EXPR and that we have >>>> flag_delete_null_pointer_checks to allow targest to declare that 0 is a >>>> valid >>>> object pointer (and thus you can do 4 + -4 and reach NULL). >>> >>> >>> Thanks. So the tricky point is that we are not allowed to transform g into f >>> below: >>> >>> char*f(char*p){return p+4;} >>> char*g(char*p){return (char*)((intptr_t)p+4);} >>> >>> That makes sense and seems much easier to guarantee than I feared, nice. >>> >>> (on the other hand, only RTL is able to simplify (long)p+4-(long)(p+4)) >> >> Hmm, yeah - we have some match.pd stuff to handle these kind of cases, >> like p + ((long)p2 - (long)p1)) and also (long)(p + x) - (long)p. >> >> OTOH to handle (long)p + 4 - (long)(p + 4) the only thing we need is to >> transform (long)(p + 4) to (long)p + 4 ... that would simplify things but >> of course we cannot ever undo that canonicalization if the result is >> ever converted back to a pointer. But maybe we can value-number it >> the same with some tricks... (might be worth to file a bugreport) >> >> Richard. >> >>> -- >>> Marc Glisse