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
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 325a765..aa392b0 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -648,6 +648,10 @@
     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 @@
       // 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 fb89cc8..5422b8b 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1784,3 +1784,17 @@
     }
 }
 
+// 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}}
+  }
+}