Teach the static analyzer that NSLog() and friends do not hold on to object references (thus extending their lifetime).

llvm-svn: 156346
This commit is contained in:
Ted Kremenek 2012-05-08 00:12:09 +00:00
parent 952b4c11fe
commit ececf9f0ae
2 changed files with 20 additions and 0 deletions

View File

@ -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

View File

@ -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}}
}
}