We defined (on the mailing list and here on phabricator) 2 different cases where retrieving information about a control dependency condition is very important:
- When the condition's last write happened in a different stack frame
- When the collapse point of the condition (when we can constrain it to be true/false) didn't happen in the actual condition.
It seems like we solved this problem with the help of expression value tracking, and have started working on better diagnostics notes about this process.
Expression value tracking is nothing more than registering a variety of visitors to construct reports about it. Each of the registered visitors (ReturnVisitor, FindLastStoreVisitor, NoStoreFuncVisitor, etc) have something to go by: a MemRegion, an SVal, an ExplodedNode, etc. For this reason, better explaining a last write is super simple, we can always just pass on some more information to the visitor in question (as seen in D65575).
ConditionBRVisitor is a different beast, as it was built for a different purpose. It is responsible for constructing events at, well, conditions, and is registered only once, and isn't a part of the "expression value tracking family". Unfortunately, it is also the visitor to tinker with for constructing better diagnostics about the collapse point problem.
This creates a need for alternative way to communicate with ConditionBRVisitor that a specific condition is being tracked for for the reason of being a control dependency. Since at almost all PathDiagnosticEventPiece construction the visitor checks interestingness, it makes sense to pair interestingness with a reason as to why we marked an entity as such.
We usually rely on our "unhandled switch case" warnings for noticing all the places which we need to expand when we're adding a new case. Your approach requires adding static asserts all over the place instead - not sure what's better. I guess they're not generally mutually exclusive, however NumTrackingKinds makes it impossible to handle all cases in a switch (because NumTrackingKinds itself wouldn't ever be handled). I took some sort of middleground approach in CFGTerminator::Kind in D61814 but i'm very much open to suggestions.