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

Reply via email to