]> granicus.if.org Git - clang/commitdiff
Add a PostVisitBlockExpr() method to RetainReleaseChecker to query for
authorTed Kremenek <kremenek@apple.com>
Thu, 26 Nov 2009 02:38:19 +0000 (02:38 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 26 Nov 2009 02:38:19 +0000 (02:38 +0000)
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

lib/Analysis/CFRefCount.cpp
test/Analysis/retain-release.m

index 06aa6bd2791f63696e216f6881efbb3653c83a64..17a69a2b5a417d8edfe83585e5031237f914bf8e 100644 (file)
@@ -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.
 //===----------------------------------------------------------------------===//
index 8c3fda27cc332ed9ccc32f0f41f1d82298882775..bc9f0b7ef4441839d8423c457f3cd4abd5e1ea45 100644 (file)
@@ -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