https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63484
Bug ID: 63484 Summary: misleading/obsolete -fdelete-null-pointer-checks documentation Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: vincent-gcc at vinc17 dot net The current -fdelete-null-pointer-checks documentation is: > Assume that programs cannot safely dereference null pointers, and that no > code or data element resides there. This enables simple constant folding > optimizations at all optimization levels. In addition, other optimization > passes in GCC use this flag to control global dataflow analyses that > eliminate useless checks for null pointers; these assume that if a pointer is > checked after it has already been dereferenced, it cannot be null. (both in the manual https://gcc.gnu.org/onlinedocs/gcc-4.9.1/gcc/Optimize-Options.html#Optimize-Options and the man page). However a new check is done as of GCC 4.9, according to: http://blog.mycre.ws/articles/bind-and-gcc-49/ and in particular: https://gcc.gnu.org/gcc-4.9/porting_to.html "GCC might now optimize away the null pointer check in code like: int copy (int* dest, int* src, size_t nbytes) { memmove (dest, src, nbytes); if (src != NULL) return *src; return 0; } The pointers passed to memmove (and similar functions in <string.h>) must be non-null even when nbytes==0, so GCC can use that information to remove the check after the memmove call. Calling copy(p, NULL, 0) can therefore deference a null pointer and crash." So, this new check makes the old -fdelete-null-pointer-checks documentation "Assume that programs cannot safely dereference null pointers, and that no code or data element resides there." obsolete. Indeed, even though calling memmove (dest, NULL, 0); is invalid, it doesn't mean that the null src pointer is dereferenced by memmove (this is not needed if nbytes is 0 like here) or that data reside there. Said otherwise, the developer may think "I know that no data reside at address 0, and that null pointers are never dereferenced (otherwise the program would crash)." and deduce that the -fdelete-null-pointer-checks option is safe on his code. However it isn't necessarily, just because of some ISO C rule that makes some function call invalid (and many developers may not be aware of it, as this rule is very unintuitive). So, the documentation should be updated. Alternatively the option could be split between one that removes checks because of code that is obviously wrong (e.g. would yield a crash in practice on most platforms, or has semantically no meanings) and one that removes checks because of any invalid code.