https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103255

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I think the bug is in:
      else if (flag_delete_null_pointer_checks
               && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr)))
        {
         /* For -fdelete-null-pointer-checks -fno-wrapv-pointer we don't
         allow going from non-NULL pointer to NULL.  */
           if(!range_includes_zero_p (&r))
            return true;
        }

If !off_cst (not this case), I think before return true here we need
r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
- we are going from the base pointer which is known not to be NULL to that +
some unknown offset, all we can say is that the result is not NULL, but we
don't really know the exact details.
For the off_cst case (probably only when it is actually constant, i.e. off_cst
&&  off.to_constant (&offi), we could use something based on r, but will need
to add the offi / BITS_PER_UNIT addend to the range, probably verify the result
doesn't include zero and if it would, use that range_nonzero too.

For the addition, not sure if that would be range_op_handler (PLUS_EXPR,
type)->fold_range or range_op_handler (POINTER_PLUS_EXPR, type)->fold_range or
what.

Because, with the code as is, we end up with the original r for the base
hdr_3: struct header * [4194336B, 4194336B]
and instead of returning range unsigned int * [4194340B, 4194340B] we return
incorrect unsigned int * [4194336B, 4194336B]

Or does this code rely on pointer ranges to be always just range_zero,
range_nonzero or varying and nothing else?  If so, it should normalize
INTEGER_CSTs used in addresses etc. into range_zero or range_nonzero and
nothing else...

Reply via email to