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