https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95663
--- Comment #8 from rguenther at suse dot de <rguenther at suse dot de> --- On Mon, 15 Jun 2020, redi at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95663 > > --- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> --- > So yes, the static_cast should evaluate to zero, Thanks for the clarification. > but if it's followed by a > dereference then it seems reasonable to expect -fdelete-null-pointer-checks to > optimize away the handling for zero. -fdelete-null-pointer-checks optimizes NULL pointer checks _after_ a dereference. This case is first checking and then dereferencing. GCC sees <bb 2> [local count: 1073741824]: if (base_2(D) != 0B) goto <bb 3>; [70.00%] else goto <bb 4>; [30.00%] <bb 3> [local count: 751619278]: iftmp.1_3 = base_2(D) + 18446744073709551612; <bb 4> [local count: 1073741824]: # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)> _5 = MEM[(int *)iftmp.1_1 + 4B]; in getter(). So this is more about if-conversion or in the GCC case path isolation where I'd actually question that MEM[0B + 4B] is an "obvious" null pointer dereference ;) It's more obvious in the IL for field(): <bb 2> [local count: 1073741824]: if (base_2(D) != 0B) goto <bb 3>; [70.00%] else goto <bb 4>; [30.00%] <bb 3> [local count: 751619278]: iftmp.0_3 = base_2(D) + 18446744073709551612; <bb 4> [local count: 1073741824]: # iftmp.0_1 = PHI <iftmp.0_3(3), 0B(2)> _5 = iftmp.0_1->D.2309.y; but my point is I guess that the C++ FE has a more "native" view of this and should maybe elide the NULL pointer check when the static_cast is dereferenced. Because eliding the check and isolating the (not NULL!) dereference is sth different.