Alright, the following patch was tested and it works

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))
     {
-- 
2.8.3


-Manish


On Thu, Jun 30, 2016 at 6:45 PM, Richard Biener
<richard.guent...@gmail.com> wrote:
> On Thu, Jun 30, 2016 at 2:03 PM, Manish Goregaokar <man...@mozilla.com> wrote:
>> What about ptr + intptr_t? I guess we should check nonnegative for op1 then?
>
> op1 will always be nonnegative as it is forced to sizetype type (which
> is unsigned).
>
> Richard.
>
>> -Manish
>>
>>
>> On Thu, Jun 30, 2016 at 5:25 PM, Richard Biener
>> <richard.guent...@gmail.com> wrote:
>>> On Thu, Jun 30, 2016 at 1:17 PM, Manish Goregaokar <man...@mozilla.com> 
>>> wrote:
>>>> gcc/ChangeLog:
>>>>     PR c/71699
>>>>     * fold-const.c (tree_binary_nonzero_warnv_p): Allow
>>>>     pointer addition to also be considered nonzero.
>>>> ---
>>>>  gcc/fold-const.c | 20 +++++++++++++-------
>>>>  1 file changed, 13 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/gcc/fold-const.c b/gcc/fold-const.c
>>>> index 3b9500d..eda713e 100644
>>>> --- a/gcc/fold-const.c
>>>> +++ b/gcc/fold-const.c
>>>> @@ -13200,16 +13200,22 @@ tree_binary_nonzero_warnv_p (enum tree_code code,
>>>>      {
>>>>      case POINTER_PLUS_EXPR:
>>>>      case PLUS_EXPR:
>>>> -      if (ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_UNDEFINED (type))
>>>> +      if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_UNDEFINED (type))
>>>> +          || POINTER_TYPE_P (type))
>>>>      {
>>>> +      /* Pointers are always nonnegative, check integers.  */
>>>> +      if (ANY_INTEGRAL_TYPE_P (type))
>>>> +      {
>>>> +          sub_strict_overflow_p = false;
>>>> +          if (!tree_expr_nonnegative_warnv_p (op0,
>>>> +                              &sub_strict_overflow_p)
>>>> +              || !tree_expr_nonnegative_warnv_p (op1,
>>>> +                             &sub_strict_overflow_p))
>>>> +            return false;
>>>> +      }
>>>>        /* With the presence of negative values it is hard
>>>>           to say something.  */
>>>> -      sub_strict_overflow_p = false;
>>>> -      if (!tree_expr_nonnegative_warnv_p (op0,
>>>> -                          &sub_strict_overflow_p)
>>>> -          || !tree_expr_nonnegative_warnv_p (op1,
>>>> -                         &sub_strict_overflow_p))
>>>> -        return false;
>>>> +
>>>
>>> Hmm, note that op1 of POINTER_PLUS_EXPR _is_ an integer that needs to be 
>>> treated
>>> as signed.
>>>
>>> POINTER_PLUS_EXPR is special in other ways in that iff
>>> flag_delete_null_pointer_checks
>>> is set we can assume that ptr + non-zero is never zero.  Thus simply do
>>>
>>>    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));
>>>
>>> OTOH ptr + -(uintptr_t)ptr is valid from a POINTER_PLUS_EXPR
>>> perspective as GCC does
>>> not have a special tree code for pointer subtraction (but IIRC it uses
>>> MINUS_EXPR on integers
>>> for this).
>>>
>>> Richard.
>>>
>>>
>>>>        /* One of operands must be positive and the other non-negative.  */
>>>>        /* We don't set *STRICT_OVERFLOW_P here: even if this value
>>>>           overflows, on a twos-complement machine the sum of two
>>>> --
>>>> 2.8.3

Reply via email to