CF-retain/release checker:
- Fix regression reported in <rdar://problem/6452745>.  After a null check, null references to resources should not have a retain count.  This regression was caused by removing the call to "GRTransferFuncs::EvalAssume" in BasicConstraintManager.
- Added a test case to test this behavior.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61155 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/NSString.m b/test/Analysis/NSString.m
index a56c5b8..ab503fa 100644
--- a/test/Analysis/NSString.m
+++ b/test/Analysis/NSString.m
@@ -15,6 +15,7 @@
 extern const CFAllocatorRef kCFAllocatorDefault;
 extern CFTypeRef CFRetain(CFTypeRef cf);
 typedef const struct __CFDictionary * CFDictionaryRef;
+const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key);
 extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...);
 typedef signed char BOOL;
 typedef int NSInteger;
@@ -27,6 +28,7 @@
 @protocol NSObject
 - (BOOL)isEqual:(id)object;
 - (oneway void)release;
+- (id)retain;
 @end
 @protocol NSCopying
 - (id)copyWithZone:(NSZone *)zone;
@@ -132,14 +134,22 @@
 }
 
 NSString* f10() {
-  
   static NSString* s = 0;
-  
   if (!s) s = [[NSString alloc] init];
-    
   return s; // no-warning
 }
 
+// Test case for regression reported in <rdar://problem/6452745>.
+// Essentially 's' should not be considered allocated on the false branch.
+// This exercises the 'EvalAssume' logic in GRTransferFuncs (CFRefCount.cpp).
+NSString* f11(CFDictionaryRef dict, const char* key) {
+  NSString* s = (NSString*) CFDictionaryGetValue(dict, key);
+  [s retain];
+  if (s) {
+    [s release];
+  }
+}
+
 @interface C1 : NSObject {}
 - (NSString*) getShared;
 + (C1*) sharedInstance;