The easy solution is to use smart pointers. If you really want for “copies” of your pointer to also be nullified use a combination of shared_ptr and weak_ptr.
......
Concerning low-level code: It too should use at least std::unique_ptr instead of raw pointers. With just some minimal support for function inlining it is as efficient as what you are proposing. shared_ptr has some overhead, but unique_ptr doesn’t.

The feature you want could just be a compiler flag. It does not have to be standardized to be able to do this. A static analyzer could also look for places in the code where a delete is not immediately followed by zeroing the pointer. One big exception for this is destructors: zeroing the pointer inside the destructor can (and will) be optimized out because the lifetime of the object containing the pointer has ended.

unique_ptr and shared_ptr have two distinct paradigms .
1-
unique_ptr moves the ownership totally, and to get back ownership , the callee need to return a unique_ptr 
{
  unique_ptr p=...;
  //assuming callee1 returns a unique_ptr 
  p = move(callee1(move(p)));
}
BUT!!!, By the time callee1 returns, we don't know if the original resource or different resource is returned. 
2-
shared_ptr models sharing ownership, but only the counter decides when to free the resource.

With the proposal + 'passing by reference' guideline, we are modeling a paradigm, of allocate in one location, free from anywhere and all are notified.

But definitely,  if it can be done by a compiler flag then it does the job.