https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88367
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- In GCC 8 we had: else if (code == POINTER_PLUS_EXPR) { /* For pointer types, we are really only interested in asserting whether the expression evaluates to non-NULL. */ if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1)) set_value_range_to_nonnull (vr, expr_type); and now we have: else if (code == POINTER_PLUS_EXPR) { /* For pointer types, we are really only interested in asserting whether the expression evaluates to non-NULL. */ if (!range_includes_zero_p (&vr0) || !range_includes_zero_p (&vr1)) vr->set_nonnull (expr_type); I think range_is_nonnull (&vr1) was pretty much never true before, that needs vr1 (which is the integral offset) to be exactly ~[0, 0]; here we had constant offset there (-24UL). So, if the UB stuff kernel is doing is meant to be considered ok for -fno-delete-null-pointer-checks, we either need to guard this condition on flag_delete_null_pointer_checks, or think of what we want to support and what we don't. E.g. do we want to treat pointer wrapping as UB? A problem is that POINTER_PLUS_EXPR last argument is unsigned sizetype, so negative offsets appear as very large positive ones. So, perhaps do we want to conclude that if vr0 doesn't include zero and vr1 is guaranteed not to have most significant bit set (i.e. appear as negative), then the result is nonnull, otherwise varying? Of course for flag_delete_null_pointer_checks do what we do right now.