[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