diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-11-26 02:38:19 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-11-26 02:38:19 +0000 |
commit | 38cc6bca5c172e2888c86fb0bef6883db0692cf6 (patch) | |
tree | 6a4d2c7cf1d6a631e5ba099880ab38ddb87bb034 | |
parent | a6d73af984d9633cd3b412f01b35edf7463dd31c (diff) |
Add a PostVisitBlockExpr() method to RetainReleaseChecker to query for
the set of variables "captured" by a block. Until the analysis gets
more sophisticated, for now we stop the retain count tracking of any
objects (transitively) referenced by these variables.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89929 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 28 | ||||
-rw-r--r-- | test/Analysis/retain-release.m | 2 |
2 files changed, 27 insertions, 3 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 06aa6bd279..17a69a2b5a 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -24,6 +24,7 @@ #include "clang/Analysis/PathSensitive/GRTransferFuncs.h" #include "clang/Analysis/PathSensitive/CheckerVisitor.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/StmtVisitor.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ImmutableMap.h" @@ -3646,10 +3647,35 @@ class VISIBILITY_HIDDEN RetainReleaseChecker CFRefCount *TF; public: RetainReleaseChecker(CFRefCount *tf) : TF(tf) {} - static void* getTag() { static int x = 0; return &x; } + static void* getTag() { static int x = 0; return &x; } + + void PostVisitBlockExpr(CheckerContext &C, const BlockExpr *BE); }; } // end anonymous namespace + +void RetainReleaseChecker::PostVisitBlockExpr(CheckerContext &C, + const BlockExpr *BE) { + + // Scan the BlockDecRefExprs for any object the retain/release checker + // may be tracking. + if (!BE->hasBlockDeclRefExprs()) + return; + + const GRState *state = C.getState(); + const BlockDataRegion *R = + cast<BlockDataRegion>(state->getSVal(BE).getAsRegion()); + + BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(), + E = R->referenced_vars_end(); + + if (I == E) + return; + + state = state->scanReachableSymbols<StopTrackingCallback>(I, E).getState(); + C.addTransition(state); +} + //===----------------------------------------------------------------------===// // Transfer function creation for external clients. //===----------------------------------------------------------------------===// diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 8c3fda27cc..bc9f0b7ef4 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -1281,7 +1281,6 @@ void test_blocks_1_pos(void) { ^{}(); } -#if 0 void test_blocks_1_indirect_release(void) { NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning ^{ [number release]; }(); @@ -1292,7 +1291,6 @@ void test_blocks_1_indirect_retain(void) { NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning ^{ [number retain]; }(); } -#endif void test_blocks_1_indirect_release_via_call(void) { NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning |