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