]> granicus.if.org Git - clang/commitdiff
Add really basic support for blocks in the retain/release checker. For now, anytime...
authorTed Kremenek <kremenek@apple.com>
Wed, 25 Nov 2009 01:35:18 +0000 (01:35 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 25 Nov 2009 01:35:18 +0000 (01:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89831 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 433e350acccbb9eb9b9ef12767aa47eba76489a9..c0d306d57cdc7c617d17742b3530ec15c4da0de3 100644 (file)
@@ -3052,9 +3052,20 @@ void CFRefCount::EvalCall(ExplodedNodeSet& Dst,
                           GRStmtNodeBuilder& Builder,
                           CallExpr* CE, SVal L,
                           ExplodedNode* Pred) {
-  const FunctionDecl* FD = L.getAsFunctionDecl();
-  RetainSummary* Summ = !FD ? Summaries.getDefaultSummary()
-                        : Summaries.getSummary(const_cast<FunctionDecl*>(FD));
+
+  RetainSummary *Summ = 0;
+  
+  // FIXME: Better support for blocks.  For now we stop tracking anything
+  // that is passed to blocks.
+  // FIXME: Need to handle variables that are "captured" by the block.
+  if (dyn_cast_or_null<BlockTextRegion>(L.getAsRegion())) {
+    Summ = Summaries.getPersistentStopSummary();
+  }
+  else {
+    const FunctionDecl* FD = L.getAsFunctionDecl();
+    Summ = !FD ? Summaries.getDefaultSummary() :
+                 Summaries.getSummary(const_cast<FunctionDecl*>(FD));
+  }
 
   assert(Summ);
   EvalSummary(Dst, Eng, Builder, CE, 0, *Summ,
index 76149bc021bc79773e09624299cb3abce438522f..8c3fda27cc332ed9ccc32f0f41f1d82298882775 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=basic -verify %s
-// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=region -verify %s
+// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=basic -fblocks -verify %s
+// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=region -fblocks -verify %s
 
 #if __has_feature(attribute_ns_returns_retained)
 #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
@@ -1272,3 +1272,36 @@ void test_panic_pos_2(int x) {
     panic();
 }
 
+//===----------------------------------------------------------------------===//
+// Test uses of blocks (closures)
+//===----------------------------------------------------------------------===//
+
+void test_blocks_1_pos(void) {
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}}
+  ^{}();
+}
+
+#if 0
+void test_blocks_1_indirect_release(void) {
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+  ^{ [number release]; }();
+}
+
+void test_blocks_1_indirect_retain(void) {
+  // Eventually this should be reported as a leak.
+  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
+  ^(NSObject *o){ [o release]; }(number);
+}
+
+void test_blocks_1_indirect_retain_via_call(void) {
+  // Eventually this should be reported as a leak.
+  NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+  ^(NSObject *o){ [o retain]; }(number);
+}
+