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

Gábor Kozár kozargabor at gmail.com
Tue Jul 16 04:21:04 PDT 2013


Hi Jordan,

Thanks for the answer!

> *Objects that live on the stack don't have symbols; the properties of a
stack object's region is entirely known and doesn't need to be symbolic.
It's a VarRegion, not a SymbolicRegion.*

I'm kind of confused about the difference between SVal and SymExpr. I
understand that a MemRegion models a region of the memory, i.e. this
contains a value that can be obtained using
context.getState()->getSVal(memRegion). My impression is that SVal is just
a bridge between SymExpr and MemRegion, where SymExpr actually represents
the symbolic values assigned during analysis. Is this about right?

> *Additionally, symbol death is not quite the same as local variable
death. If the value of a local variable is symbolic, and that value gets
copied somewhere else, the symbol won't die when the local variable does.*

This is the kind of code I'm talking about:

void foo()
{
      Foo f;
}

As far as I can tell, 'f' here is actually a MemRegion, which seems
counter-intuitive to me. I want to be notified when the 'f' object dies.
checkDeadSymbols doesn't seem to work, I dump everything every time it's
called and I don't get anything resembling what I'm looking for. I also
tried checkRegionChanges, but that doesn't seem to tell me either.

What I'm left doing is looking when a dtor is called. checkPostCall is
actually a good idea on that, although I've also figured out how to get the
'this' region from only a CheckerContext:

const CXXThisRegion* thisRegion =
context.getStoreManager().getRegionManager().getCXXThisRegion(
            dtor->getThisType(context.getASTContext()),
            context.getLocationContext());

SVal thisVal = context.getState()->getSVal(thisRegion);
const MemRegion* objectRegion = thisVal.getAsRegion(); // this is 'f'

What I'm trying to do here is to check what resources the object destructor
deallocates. checkDeadSymbols does tell me when a member pointer is freed
using delete, but this unfortunately happens after both checkEndFunction
and checkPostCall for the destructor, so it is not useful for me. Or it
would be, if I had been able to get the MemRegion that contains the SymExpr
that died - this would get me the FieldRegion, in which the pointer was
stored, and that would be enough.
Unfortunately, I get UnknownSpaceRegion if I try to do this:
context.getStoreManager().getRegionManager().getSymbolicRegion(deadSymbol)->getSuperRegion().
This kind of makes sense, since the symbol is dead, so the information
about where it has been is probably already lost.

I also tried to do checkPreStmt for CXXDeleteExpr, but here I have no clue
as to how to get the SVal/SymExpr/MemRegion that is being deleted.

So I'm kind of running out of ideas here. Could you give me some pointers?

Thanks!

Gabor

2013/7/15 Jordan Rose <jordan_rose at apple.com>

> Hi, Gabor. Objects that live on the stack don't have symbols; the
> properties of a stack object's region is entirely known and doesn't need to
> be symbolic. It's a VarRegion, not a SymbolicRegion.
>
> The good news is that regions are also uniqued, and so if you're just
> looking to identify an object, using the region as the key is often
> reasonable as well, possibly with a call to stripCasts().
>
> Additionally, symbol death is not *quite* the same as local variable
> death. If the value of a local variable is symbolic, and that value gets
> copied somewhere else, the symbol won't die when the local variable does.
> (Symbol information is basically garbage collected—each cleanup starts by
> crawling through all the live regions and values to see what's still
> accessible.) Local variables have very well-defined scope rules, so all of
> their control is in the CFG.
>
> Rather than using the 'this' region and checkEndFunction, why not use
> checkPostCall and CXXDestructorCall's getCXXThisVal? (What are you actually
> trying to do?)
>
> Jordan
>
>
> On Jul 13, 2013, at 10:30 , Gábor Kozár <kozargabor at gmail.com> wrote:
>
> Hi,
>
>
> I'm using the Clang Static Analyzer from Clang 3.3. I want to check
> object's state when they die. I tried using checkDeadSymbols, but according
> to the SymbolReaper, the objects of interest never die. This is my test
> code:
>
> struct Foo
> {
>      int* x;
>      Foo() { x = new int(10); }
> };
>
> int main(int argc, const char** argv)
> {
>       Foo f;
>       return 0;
> }
>
> The int* does die, but f does not. (I cannot check this directly: I just
> made the SymbolReaper print all symbols are regions that died, using the
> dead_begin(), etc. and region_begin() etc. methods). Why is this, and how
> can I work around it?
>
> Even when there is a user-made destructor, which I can get using
> checkEndFunction, I'm unable to get back the symbol that represents 'f'. I
> spent like an hour digging through clang::ento's reference, and this was my
> best tip:
>
> const CXXThisRegion* thisRegion =
> context.getStoreManager().getRegionManager().getCXXThisRegion(
>             dtor->getThisType(context.getASTContext()),
>             context.getLocationContext());
>
> Unfortunately, this gives something that doesn't seem to have anything to
> do with 'f'. How can I get the symbol representing 'f', using only the
> CheckerContext and the const CXXDestructorDecl* I can obtain from the
> LocationContext?
>
> I'm really stuck, and any help would be greatly appreciated. Thank you!
>
> Gabor
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130716/c600eb2f/attachment.html>


More information about the cfe-dev mailing list