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