I wrote a checker similar to the SimpleStreamChecker except that the close function that moves the state of the stream to released, takes a second parameter, a callback, for instance
close(FILE *, mycallback).
When the stream moves to release state, the callback is executed.
The “close” function is defined externally so that the checker cannot reason on it except using the rules I give it in checkPostCall callback. How can I make the analyzer aware that the callback has to be executed when the state move to release?
Unfortunately, allowing checkers to trigger an immediate inlining of a function is quite tricky to implement, and we don't have a ready-made mechanism for that (though some of the existing checkers could make use of such functionality).
It might theoretically be possible, within a checker callback, to manually construct an exploded graph node that represents entering a stack frame of the callback function, and then addTransition() to such node (similarly to how ExprEngine does that) and see what happens. That'd be an interesting problem to tackle, and such mechanism would be good to have.
Also, are you sure it is necessary to model the callback exactly in your use case? Maybe a simple invalidation/escape pass would suffice to avoid false positives?
See how, for example, dispatch_sync() is modeled in lib/Analysis/BodyFarm.cpp.
Once you have a fake body, the path-sensitive engine would be able to execute it with the desired effect. It's much easier than what i originally proposed.
I think this is a great use case for the body farm!
There is one possible mistake that is easy to make when one uses this feature. (Which does not affect your example, so do not worry about that. I just wanted to share this for future reference.)
Thank you for your very useful input, both of you!
However, it is not clear to me how I should proceed. At which stage of the analysis should I do this?
If we take the example below:
func(int *, void (*callback)(void))
Should I implement the callback checkBeginFunction and when I hit ‘func’, create the body?
Will the analyzer pick the definition on the fly? Or maybe at checkPreCall?
It is not clear to me how this get inserted properly in the ExplodedGraph.
Also, I don’t see in the clang code base any user of BodyFarm.cpp’s defined classes.