[cfe-commits] r153489 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp test/Analysis/retain-release-region-store.m test/Analysis/retain-release.m

Ted Kremenek kremenek at apple.com
Mon Mar 26 18:12:45 PDT 2012


Author: kremenek
Date: Mon Mar 26 20:12:45 2012
New Revision: 153489

URL: http://llvm.org/viewvc/llvm-project?rev=153489&view=rev
Log:
Change RetainCountChecker to eagerly "escape" retained objects when they are
assigned to a struct.  This is fallout from inlining results, which expose
far more patterns where people stuff CF objects into structs and pass them
around (and we can reason about it).  The problem is that we don't have
a general way to detect when values have escaped, so as an intermediate step
we need to eagerly prune out such tracking.

Fixes <rdar://problem/11104566>.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
    cfe/trunk/test/Analysis/retain-release-region-store.m
    cfe/trunk/test/Analysis/retain-release.m

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=153489&r1=153488&r2=153489&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Mon Mar 26 20:12:45 2012
@@ -3341,6 +3341,12 @@
       // the binding).
       escapes = (state == (state->bindLoc(*regionLoc, val)));
     }
+    if (!escapes) {
+      // Case 4: We do not currently model what happens when a symbol is
+      // assigned to a struct field, so be conservative here and let the symbol
+      // go. TODO: This could definitely be improved upon.
+      escapes = !isa<VarRegion>(regionLoc->getRegion());
+    }
   }
 
   // If our store can represent the binding and we aren't storing to something

Modified: cfe/trunk/test/Analysis/retain-release-region-store.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release-region-store.m?rev=153489&r1=153488&r2=153489&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release-region-store.m (original)
+++ cfe/trunk/test/Analysis/retain-release-region-store.m Mon Mar 26 20:12:45 2012
@@ -100,6 +100,10 @@
   NSDate* f;
 };
 
+// FIXME: We should be warning about a use-after-free here, but we
+// temporarily "escape" retain counted objects stored to structs very eagerly
+// until we can properly tell whether they have escaped via a return value
+// or not.
 CFAbsoluteTime f4() {
   struct foo x;
   
@@ -110,7 +114,8 @@
   CFDateGetAbsoluteTime(date); // no-warning
   x.f = (NSDate*) date;  
   [((NSDate*) date) release];
-  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released}}
+  // FIXME: the following line should warn.
+  t = CFDateGetAbsoluteTime(date);   // no-warning
   return t;
 }
 

Modified: cfe/trunk/test/Analysis/retain-release.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.m?rev=153489&r1=153488&r2=153489&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release.m (original)
+++ cfe/trunk/test/Analysis/retain-release.m Mon Mar 26 20:12:45 2012
@@ -1668,6 +1668,29 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Test returning allocated memory in a struct.
+// 
+// We currently don't have a general way to track pointers that "escape".
+// Here we test that RetainCountChecker doesn't get excited about returning
+// allocated CF objects in struct fields.
+//===----------------------------------------------------------------------===//
+void *malloc(size_t);
+struct rdar11104566 { CFStringRef myStr; };
+struct rdar11104566 test_rdar11104566() {
+  CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning
+  struct rdar11104566 V;
+  V.myStr = cf;
+  return V; // no-warning
+}
+
+struct rdar11104566 *test_2_rdar11104566() {
+  CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning
+  struct rdar11104566 *V = (struct rdar11104566 *) malloc(sizeof(*V));
+  V->myStr = cf;
+  return V; // no-warning
+}
+
+//===----------------------------------------------------------------------===//
 // ObjC literals support.
 //===----------------------------------------------------------------------===//
 





More information about the cfe-commits mailing list