https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67376
--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> --- As for the non-NULL checks, struct A { int e[2]; }; constexpr A a { { 0, 1 } }; static_assert (a.e != 0, ""); static_assert (&a.e[1] != 0, ""); static_assert (&a.e[2] != 0, ""); static_assert (a.e + 1 != 0, ""); static_assert (a.e + 2 != 0, ""); static_assert (&a.e[-1] != 0, ""); static_assert (&a.e[3] != 0, ""); the first 3 static_asserts are handled by match.pd: (simplify (cmp (convert? addr@0) integer_zerop) (if (tree_single_nonzero_warnv_p (@0, NULL)) { constant_boolean_node (cmp == NE_EXPR, type); }))) case. The last two as well, but those are invalid and we really should be diagnosing that in the C++ FE somewhere. The a.e + 1 != 0 and a.e + 2 != 0 cases we used to fold them because try_move_mult_to_index would fold them into ADDR_EXPR of some field, which intentionally no longer happens. So, I guess we want instead some simplification of POINTER_PLUS_EXPR<ADDR_EXPR<something>, INTEGER_CST> that would say use get_inner_reference on something, add (in offset_int?) the constant offset to it and determine if it is always non-zero. The question is what rule should we use. Any positive constant offset from a known non-zero base address? Something different (like only positive constant offset from 0 up to and including the size of the var)? Perhaps if the constant offset modulo alignment of the var is known to be non-zero always, no matter if the base var has known non-zero base address or not? Or just whenever the constant offset is > 0 (or optionally also smaller than size of the var)? I mean, for &a.e + 1, even if &a is NULL, &a.e + 1 still would be non-NULL, unless the a var is partly at the end of the address space and partly at the beginning.