No, I never said to depend solely (or largely) on analysis tools. I said "trust you inputs only when you should". Your example is one of many examples where you shouldn't.
Functions that expose APIs or any sort of publicly accessible methods obviously fall into the class of functions that can't trust their parameters. Anything with that sort of exposed surface area needs more defensive techniques.
Other types of code don't necessarily need that level of defensive techniques. Private member functions of C++ classes, for example, can safely decide to trust their inputs. If every private member of every class needed to replicate the parameter and error checking of everything in the callstack above it, that adds a lot of redundancy.
If I have code like
if (ptr)
dosomething(ptr)
and it can be demonstrated that every caller of dosomething() has that null check then dosomething() doesn't really need to check that parameter.
If it does decide to check the parameter, then dosomething() has to decide what to do if it is null. Return an error? Should callers handle that error? What would that error be? E_POINTER or some such? A caller has more information about handling such an error. Of course, it's about the same to have
if (dosomething(ptr) == E_POINTER)
{
// handle bad pointer
}
except you've just handed parameter checking to the callee, which is bad from encapsulation point of view.
At some point, you have to decide that you've done enough parameter validation and get on with actually doing something useful.
Further, if you're using dynamic or static code coverage tools, then multiple redundant levels of checks will obviously demonstrate that you have a lot of unreachable code. This bloats modules and hurts performance. Then you need additional optimization tools to fix that.
I certainly agree with your last sentence. Obviously defining interface contracts with markup and using code analysis tools is only part of the solution - those merely guide you as to where you need checking and where it's redundant.