Added a test: 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