Earlier quoted context omitted.
The address of p could have been taken somewhere earlier and stored in a global that foo accesses, or a similar path to that; and of course, p could itself be a global. Indeed, if the purpose of foo is to make p non-null and point to valid memory, then by optimising away that code you have broken a valid program. If the compiler doesn't know if foo may modify p, then it can't remove the call. Even if it can prove tha…
But in fact compilers do regularly prove such things as, "this function call did not touch that local variable". Escape analysis is a term related to this. I'm more of two minds about that other step, where the compiler goes like, "here in the printf call the p will be dereferenced, so it surely is non-null, so we silently optimize that other thing out where we consider the possibility of it being null". Also @joshua…
int main() {
char *p;
p = mmap(0, 65536, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
// ...
return __builtin_popcountl((uintptr_t)p);
}
Or you do this: void ContinueOnError(int sig, siginfo_t *si, ucontext_t *ctx) {
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64);
xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15);
ctx->uc_mcontext.rip += xedd.length;
}
int main() {
signal(SIGSEGV, ContinueOnError);
volatile long *x = NULL;
printf("*NULL = %ld\n", *x);
}