[cfe-commits] static analysis: multiple VarRegions per VarDecl?

Zhongxing Xu xuzhongxing at gmail.com
Tue Oct 7 19:05:50 PDT 2008


On Wed, Oct 8, 2008 at 2:00 AM, Ted Kremenek <kremenek at apple.com> wrote:

>
> On Oct 6, 2008, at 11:49 PM, Zhongxing Xu wrote:
>
>  Could you show me an example where the same VarDecl should bind to
>> different region during one analysis path?
>>
>
> Hopefully here is a better example to illustrate the point I was trying to
> make.
>
> Consider:
>
> int *p = 0;
>
> for (...) {
>  if(some_condition) {
>   int j = foo();
>   if (p) (*p)++;
>   p = &j;
>  }
> }
>
> This is a very contrived example, but the point is that the variable 'j'
> goes out of scope at the end of the true block for if(some_condition), but
> 'p' still refers to the VarRegion for 'j'  (which at that point is invalid).
>
> Upon entry to if(some_condition) on a subsequent iteration of the loop,
> what should we do?  If we have one VarRegion for 'j', then the expression
> '(*p)++' will appear valid, even though it really refers to the 'j' on a
> previous loop iteration.


I think there is no such "j on a previous loop iteration". 'j' just
represents a fixed memory block on the stack, except this block is reclaimed
(shrink the stack) when we exit the true  branch. Whenever we enter the true
branch, 'j' will represent the same memory block.


> By coincidence, the value of &j may be the same across loop iterations, but
> that isn't guaranteed to be the case.


I think this is guaranteed to be the case by the C semantics.

The thing we should do is: when we exit the true branch (or more generally a
scope), we mark all local regions as invalid. Next time we enter the scope,
we reget them and mark as valid. This validity property is associated with
MemRegions only, has nothing to do with VarDecl and mappings.

Once the VarRegion of 'j' is marked as invalid, any dereference of 'p' can
be recognized as illegal automatically if 'p' still points to that region.
Next time when we enter the scope and meet DeclStmt of 'j', the region is
marked as valid again, then '*p' is legal again.

The point here is that 'j' really represents the same memory block whenever
we have 'j' in scope.


>  This is also poor programming, since 'p' refers to garbage as soon as the
> compound statement for if(some_condition) finishes.
>
> There are potentially other solution than having multiple VarRegions.

We could potentially fix up all the old bindings to &j after j goes out of
> scope to point to an invalid region.


I don't think we need to fix up all bindings explicitly. We just mark the
VarRegion of 'j' as invalid, and do some check when evaluate '*p'.


>  This seems a little cumbersome, and it also causes us to lose some
> information that can be cumbersome to recover. (i.e., the region 'p' points
> to is now invalid, but what region did it point to originally?)
>
> The only reason I'm bringing this up now is not that we have to implement
> flexible bindings for VarDecl* -> VarRegions right now (if that indeed is
> what we decide to do), but that the interface for getLVal(VarDecl*) and
> getRegion(VarDecl*) that is exposed in GRStateManager and StoreManager
> probably should take some extra parameters (e.g., const GRState*) to provide
> some context in case the StoreManager/RegionManager wishes to allow flexible
> bindings.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20081008/9bac00da/attachment.html>


More information about the cfe-commits mailing list