[PATCH PR c/71699] Handle pointer arithmetic in nonzero tree checks

Richard Biener richard.guenther@gmail.com
Thu Jun 30 13:24:00 GMT 2016


On Thu, Jun 30, 2016 at 2:03 PM, Manish Goregaokar <manish@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.guenther@gmail.com> wrote:
>> On Thu, Jun 30, 2016 at 1:17 PM, Manish Goregaokar <manish@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



More information about the Gcc-patches mailing list