What about ptr + intptr_t? I guess we should check nonnegative for op1 then?
-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