[cfe-dev] Static Analyzer: immortal objects and getting the symbol for 'this'

Jordan Rose jordan_rose at apple.com
Mon Aug 5 17:19:22 PDT 2013


On Jul 31, 2013, at 9:52 , Gábor Kozár <kozargabor at gmail.com> wrote:

> Hi Jordan,
> 
> Thanks for the reply, a lot of useful information!
> 
> 2013/7/26 Jordan Rose <jordan_rose at apple.com>
> Compiler-generated destructors aren't ignored, but trivial destructors are. This is intentional, since it simplifies the CFG and general analysis and makes the analyzer do less work, but we wouldn't have to keep it that way. Still, if the destructor is trivial, what cleanup is it supposed to be doing? (I guess if it's trivial when it's supposed to be doing cleanup it'd be a problem. An AST-traversal check might be the way to go for that, though, rather than spending the full efforts of a path-sensitive engine to tell you you didn't implement something.)
> 
> This is a significant issue, as it makes it impossible for me to efficiently clean up resources used for tracking objects. checkDeadSymbols only tells me about very-very few deaths, and I haven't yet seen it tell me that a region has died. Many objects have trivial dtors. For example, I'm now writing a checker that aims to detect invalidated iterator usages. Obviously, when an iterator object dies, I can stop tracking it. Granted, the tracking information is not too significant in this case (2 bools), but you see the problem.

Point taken. I don't think we want to be explicitly tracking lifetimes of everything, though. Perhaps you could try using SymbolReaper::isLiveRegion for every time through checkDeadSymbols? Does that have any performance issues?

(It does mean that you might get values lingering in the state when a region dies but no symbols do, but it probably won't hurt that much.)


> --
> 
> Anyhow, a different question: we have a number of custom-built checkers now, and some of which are pretty general, and probably would be useful as a built-in checker as well. I'm far from satisfied with them at this point, but once I am (hopefully by September), we could consider contributing these to the Clang repository (my boss hasn't yet agreed, but I'll be pushing the question). What is the procedure for this?

New checkers have been patches on cfe-commits (or Phabricator) in the past. There's usually more back-and-forth than a normal patch to try to make the checker general and conservative, but no formal proposal process or anything. On the other hand, a well-written description of a new checker and its motivation is definitely appreciated.)


> --
> 
> In my current checker, I need to detect whenever a particular value is used. For instance, when it appears in a function argument, or it is assigned to, etc. checkLocation will only fire for Loc-type Svals, which makes sense, except it's not useful here.
> For now my only idea is to use checkPreStmt, and search the stmt for such references... except that is terribly inefficient. I guess for now I will just look for DeclRefExpr-s and MemberExpr-s, try to obtain their SVal, then get the symbol/memregion from the SVal, then check if I have any info associated with it in the programstate (i.e. whether it is tracked)...
> Is the lack of such interface in Clang SA deliberate? I could imagine like a checkVariable(SVal val, const Expr* refExpr, const Stmt* environment, CheckerContext& context). I can imagine this would very inefficient, so it would probably need to be paired with some opt-in mechanics, like the checker has to say "I want to be notified whenever this variable is used" - maybe similarly to how checkRegionChanges are.
> Any thoughts on this?

It's not so much a deliberate absence as much as an expensive proposition. Everything anybody does is accessing a value, so if you want to essentially set a watchpoint on that value you're going to be impacting everything the analyzer is doing. And what about derived values? (e.g. $sym + 1.)

The question is definitely different between tracking variables and fields vs. tracking values. For an iterator-checker, for example, the metadata would be associated with a region, but the important thing to track is the value -- a temporary iterator is just as much associated with a container as one with an associated variable, even when it's an rvalue.

It does seem expensive to track every lvalue-to-rvalue conversion along with every function call (for operator= and such). I don't think your hypothetical checkVariable (checkValue?) would be any better, though. What do you actually need this for?

Jordan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130805/6409d7de/attachment.html>


More information about the cfe-dev mailing list