aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-05-08 00:12:09 +0000
committerTed Kremenek <kremenek@apple.com>2012-05-08 00:12:09 +0000
commitc91fdf662d4f453ce9bb975b25cec348d0ced9c6 (patch)
tree3f8c654b7b2b90a11b17098b5da829e44aae3074
parent9b79fc9c57dc9d541c2a5737c3e2c24cc68d485d (diff)
Teach the static analyzer that NSLog() and friends do not hold on to object references (thus extending their lifetime).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156346 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp6
-rw-r--r--test/Analysis/retain-release.m14
2 files changed, 20 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 325a7657e6..aa392b0860 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -648,6 +648,10 @@ public:
return getPersistentSummary(Summ);
}
+ const RetainSummary *getDoNothingSummary() {
+ return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+ }
+
const RetainSummary *getDefaultSummary() {
return getPersistentSummary(RetEffect::MakeNoRet(),
DoNothing, MayEscape);
@@ -997,6 +1001,8 @@ RetainSummaryManager::getSummary(const FunctionDecl *FD,
// libdispatch finalizers.
ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+ } else if (FName.startswith("NSLog")) {
+ S = getDoNothingSummary();
} else if (FName.startswith("NS") &&
(FName.find("Insert") != StringRef::npos)) {
// Whitelist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index fb89cc8114..5422b8bb0f 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1784,3 +1784,17 @@ void test_objc_arrays() {
}
}
+// Test NSLog doesn't escape tracked objects.
+void rdar11400885(int y)
+{
+ @autoreleasepool {
+ NSString *printString;
+ if(y > 2)
+ printString = [[NSString alloc] init];
+ else
+ printString = [[NSString alloc] init];
+ NSLog(@"Once %@", printString);
+ [printString release];
+ NSLog(@"Again: %@", printString); // expected-warning {{Reference-counted object is used after it is released}}
+ }
+}