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
<[email protected]> wrote:
> On Thu, Jun 30, 2016 at 5:14 PM, Marc Glisse <[email protected]> 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