Loosely tied to EXP34-C.
Suppose we do a pointer operation, such as dereferencing, or passing it to a function whose parameter is attributed with non null (like _Nonnull or clang::nonnull). Then, we write an if branch whose condition is this very pointer.
void tp1(int *p) { *p = 5; // expected-note@-1{{Pointer assumed non-null here}} // expected-note@-2{{Consider moving the condition here}} if (p) // expected-note@-1{{Pointer is unconditionally non-null here}} // expected-warning@-2{{Pointer is unconditionally non-null here [alpha.core.ReverseNull]}} return; }
This is a sign of code smell: We either inteded to place the condition before the operation that already expects the pointer to be non-null, or there are some other high level issues in our code. The patch adds a new checker to find and warn for similar cases.
One of the fundamental ideas here is that this is an interprocedural checker. We want to ensure that the derefence (or similar operation) unconditionally leads to the condition without interleaving assignments. This sounds a lot like a dataflow analysis! Indeed, it would be great if we had a dataflow framework already in the bag, and although there is a work on it (a lot of patches can be seen on @ymandel's profile: https://reviews.llvm.org/people/revisions/17749/), its not quite there yet.
Another thought could be, that this checker is (somewhat) redundant with DeadCodeChecker, because this checker also finds dead code, but restricted to pointers. This wasn't a deterrent in developing this alpha checker, because if an 'else' branch is not present, the dead code will not be found (despite the sode smell being there), and restricting ourselves to pointer analysis takes a lot of weight off from our constraint solvers.
I've ran the checker on a lot of projects, and the results so far look promising, and I'm looking forward to publishing them ASAP.