Best way to determine which condition branch i am on in a static analyzer checker

hey there

i am writing a static analyzer checker that needs to know if it is contained in a surrounding IfStmt, and if the current node is on the true or false branch. what is the simplest way to achieve this?

currently i am using the previous nodes ParentMap and walking back up through parents until i find an IfStmt, but i am unsure how i can tell if this node belongs to the If or an Else / Else If branch. any pointers?

ta

Well, if you’re already using ParentMap, you could see if the Stmt just below the IfStmt represents the “then” statement or the “else” statement. (Or neither, if it’s the condition!) However, if you’ve seen our talk, you’ll remember that pattern-matching against statement kinds isn’t the best way to determine control flow or assumptions:

  • The user could have used “while” or “?:” instead of “if”.
  • There could be a goto or longjmp involved.
  • You may be within an inlined function which is itself within an “if”.
  • Someone may have used an early return (or break or continue) instead of putting the rest of the block in an else-clause.

So, what are you actually trying to achieve?
Jordan

hey

i had not seen your talk, very informative. i am trying to write a checker to warn when methods are being used that became available later than the minimum deployment target. i am using the checkPreCall callback to look for C or ObjC calls that have availability information. if this is greater than the deployment target i then walk back up the ParentMap looking for an enclosing IfStmt that has a condition that is a respondsToSelector: call or a != NULL for a method with a suitable availability attribute, if one is not found then emit a warning.

but from your talk i gather that this is probably not a good way to do it. perhaps i should implement the checkBranchCondition callback and look for the correct condition and save the SVal for later. then in checkPreCall i need to get the SVal for the condition and use the ConstraintManager to work out if i am on the true branch, something like that? does this make sense? or do you have a better suggestion?

ta

Hi Richard,

I think your second thought is more of the right idea. When there is a check for availability information, the checker can record a state change along that path to record the availability. When a call requiring a minimum deployment target happens, check if that availability information is in the state. This breaks the reasoning logically into separate pieces along the path, and you are thinking more of the semantics of the check, not the syntax of how the code was written. For example, the first approach won’t work in general. What if I wrote:

if (! )
return;

call_something_that_requires_a_minimum_deployment();

In this case, there is no nesting between the if statement that does the check and the call itself. If your checker reasons about the semantics of the check along the path, then it handles all cases. In other words, I don’t think you should need to use ParentMap at all.