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...