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