summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-11-26 02:38:19 +0000
committerTed Kremenek <kremenek@apple.com>2009-11-26 02:38:19 +0000
commitf89dcdaf19ce889e469bf1eddd8ae198ee1f19a9 (patch)
tree3a067ecd41325f1810ff4935afa4d147e24148c3 /clang/lib
parent94f8c4a7d5d134d6a641876692a52899c0eaacce (diff)
downloadbcm5719-llvm-f89dcdaf19ce889e469bf1eddd8ae198ee1f19a9.tar.gz
bcm5719-llvm-f89dcdaf19ce889e469bf1eddd8ae198ee1f19a9.zip
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. llvm-svn: 89929
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Analysis/CFRefCount.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
index 06aa6bd2791..17a69a2b5a4 100644
--- a/clang/lib/Analysis/CFRefCount.cpp
+++ b/clang/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.
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud