1// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.RetainCount,deadcode -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-arc -analyzer-output=plist-multi-file -analyzer-config deadcode.DeadStores:ShowFixIts=true -o %t.plist %s 2// RUN: %normalize_plist <%t.plist | diff -ub %S/Inputs/expected-plists/objc-arc.m.plist - 3 4typedef signed char BOOL; 5typedef struct _NSZone NSZone; 6@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; 7typedef unsigned long NSUInteger; 8 9@protocol NSObject 10- (BOOL)isEqual:(id)object; 11@end 12@protocol NSCopying 13- (id)copyWithZone:(NSZone *)zone; 14@end 15@protocol NSCoding; 16@protocol NSMutableCopying; 17@protocol NSFastEnumeration 18- (void)encodeWithCoder:(NSCoder *)aCoder; 19@end 20@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; 21@end 22@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; 23@end 24@interface NSObject <NSObject> {} 25+ (id)alloc; 26- (id)init; 27- (NSString *)description; 28@end 29@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> 30- (NSUInteger)count; 31- (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt; 32+ (id)arrayWithObject:(id)anObject; 33+ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; 34+ (id)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); 35- (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); 36- (id)initWithArray:(NSArray *)array; 37@end 38 39typedef const struct __CFAllocator * CFAllocatorRef; 40extern const CFAllocatorRef kCFAllocatorDefault; 41typedef double CFTimeInterval; 42typedef CFTimeInterval CFAbsoluteTime; 43extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); 44typedef const struct __CFDate * CFDateRef; 45extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); 46 47typedef const void* objc_objectptr_t; 48__attribute__((ns_returns_retained)) id objc_retainedObject(objc_objectptr_t __attribute__((cf_consumed)) pointer); 49__attribute__((ns_returns_not_retained)) id objc_unretainedObject(objc_objectptr_t pointer); 50 51// Test the analyzer is working at all. 52void test_working() { 53 int *p = 0; 54 *p = 0xDEADBEEF; // expected-warning {{null}} 55} 56 57// Test that in ARC mode that blocks are correctly automatically copied 58// and not flagged as warnings by the analyzer. 59typedef void (^Block)(void); 60void testblock_bar(int x); 61 62Block testblock_foo(int x) { 63 Block b = ^{ testblock_bar(x); }; 64 return b; // no-warning 65} 66 67Block testblock_baz(int x) { 68 return ^{ testblock_bar(x); }; // no-warning 69} 70 71Block global_block; 72 73void testblock_qux(int x) { 74 global_block = ^{ testblock_bar(x); }; // no-warning 75} 76 77// Test that Objective-C pointers are null initialized. 78void test_nil_initialized() { 79 id x; 80 if (x == 0) 81 return; 82 int *p = 0; 83 *p = 0xDEADBEEF; // no-warning 84} 85 86// Test that we don't flag leaks of Objective-C objects. 87void test_alloc() { 88 [NSObject alloc]; // no-warning 89} 90 91// Test that CF allocations are still caught as leaks. 92void test_cf_leak() { 93 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 94 CFDateRef date = CFDateCreate(0, t); // expected-warning {{Potential leak}} 95 (void) date; 96} 97 98// Test that 'init' methods do not try to claim ownerhip of an *unowned* allocated object 99// in ARC mode. 100@interface RDar9424890_A : NSObject 101- (id)initWithCleaner:(int)pop mop:(NSString *)mop ; 102- (RDar9424890_A *)rdar9424890:(NSString *)identifier; 103@end 104@interface RDar9424890_B : NSObject 105@end 106@implementation RDar9424890_B 107- (RDar9424890_A *)obj:(RDar9424890_A *)obj { 108 static NSString *WhizFiz = @"WhizFiz"; 109 RDar9424890_A *cell = [obj rdar9424890:WhizFiz]; 110 if (cell == ((void*)0)) { 111 cell = [[RDar9424890_A alloc] initWithCleaner:0 mop:WhizFiz]; // no-warning 112 } 113 return cell; 114} 115@end 116 117// Test that dead store checking works in the prescence of "cleanups" in the AST. 118void rdar9424882() { 119 id x = [NSObject alloc]; // expected-warning {{Value stored to 'x' during its initialization is never read}} 120} 121 122// Test 123typedef const void *CFTypeRef; 124typedef const struct __CFString *CFStringRef; 125 126@interface NSString : NSObject 127- (id) self; 128@end 129 130CFTypeRef CFCreateSomething(); 131CFStringRef CFCreateString(); 132CFTypeRef CFGetSomething(); 133CFStringRef CFGetString(); 134 135id CreateSomething(); 136NSString *CreateNSString(); 137 138void from_cf() { 139 id obj1 = (__bridge_transfer id)CFCreateSomething(); // expected-warning{{never read}} 140 id obj2 = (__bridge_transfer NSString*)CFCreateString(); 141 [obj2 self]; // Add a use, to show we can use the object after it has been transferred. 142 id obj3 = (__bridge id)CFGetSomething(); 143 [obj3 self]; // Add a use, to show we can use the object after it has been bridged. 144 id obj4 = (__bridge NSString*)CFGetString(); // expected-warning{{never read}} 145 id obj5 = (__bridge id)CFCreateSomething(); // expected-warning{{never read}} expected-warning{{leak}} 146 id obj6 = (__bridge NSString*)CFCreateString(); // expected-warning{{never read}} expected-warning{{leak}} 147} 148 149void to_cf(id obj) { 150 CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); // expected-warning{{never read}} 151 CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString(); // expected-warning{{never read}} 152 CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); // expected-warning{{never read}} 153 CFStringRef cf4 = (__bridge CFStringRef)CreateNSString(); // expected-warning{{never read}} 154} 155 156void test_objc_retainedObject() { 157 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 158 CFDateRef date = CFDateCreate(0, t); 159 id x = objc_retainedObject(date); 160 (void) x; 161} 162 163void test_objc_unretainedObject() { 164 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 165 CFDateRef date = CFDateCreate(0, t); // expected-warning {{Potential leak}} 166 id x = objc_unretainedObject(date); 167 (void) x; 168} 169 170// Previously this resulted in a "return of stack address" warning. 171id test_return() { 172 id x = (__bridge_transfer id) CFCreateString(); 173 return x; // no-warning 174} 175 176void test_objc_arrays() { 177 { // CASE ONE -- OBJECT IN ARRAY CREATED DIRECTLY 178 NSObject *o = [[NSObject alloc] init]; 179 NSArray *a = [[NSArray alloc] initWithObjects:o, (void*)0]; 180 [a description]; 181 [o description]; 182 } 183 184 { // CASE TWO -- OBJECT IN ARRAY CREATED BY DUPING AUTORELEASED ARRAY 185 NSObject *o = [[NSObject alloc] init]; 186 NSArray *a1 = [NSArray arrayWithObjects:o, (void*)0]; 187 NSArray *a2 = [[NSArray alloc] initWithArray:a1]; 188 [a2 description]; 189 [o description]; 190 } 191 192 { // CASE THREE -- OBJECT IN RETAINED @[] 193 NSObject *o = [[NSObject alloc] init]; 194 NSArray *a3 = @[o]; 195 [a3 description]; 196 [o description]; 197 } 198 { 199 // CASE 4, verify analyzer still working. 200 CFCreateString(); // expected-warning {{leak}} 201 } 202} 203 204// <rdar://problem/11059275> - dispatch_set_context and ARC. 205__attribute__((cf_returns_retained)) CFTypeRef CFBridgingRetain(id X); 206typedef void* dispatch_object_t; 207void dispatch_set_context(dispatch_object_t object, const void *context); 208 209void rdar11059275(dispatch_object_t object) { 210 NSObject *o = [[NSObject alloc] init]; 211 dispatch_set_context(object, CFBridgingRetain(o)); // no-warning 212} 213void rdar11059275_positive() { 214 NSObject *o = [[NSObject alloc] init]; // expected-warning {{leak}} 215 CFBridgingRetain(o); 216} 217void rdar11059275_negative() { 218 NSObject *o = [[NSObject alloc] init]; // no-warning 219 (void) o; 220} 221 222__attribute__((ns_returns_retained)) id rdar14061675_helper() { 223 return [[NSObject alloc] init]; 224} 225 226id rdar14061675() { 227 // ARC produces an implicit cast here. We need to make sure the combination 228 // of that and the inlined call don't produce a spurious edge cycle. 229 id result = rdar14061675_helper(); 230 *(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}} 231 return result; 232} 233 234typedef const void * CFTypeRef; 235typedef const struct __CFString * CFStringRef; 236typedef const struct __CFAllocator * CFAllocatorRef; 237extern const CFAllocatorRef kCFAllocatorDefault; 238 239extern CFTypeRef CFRetain(CFTypeRef cf); 240extern void CFRelease(CFTypeRef cf); 241 242 243void check_bridge_retained_cast() { 244 NSString *nsStr = [[NSString alloc] init]; 245 CFStringRef cfStr = (__bridge_retained CFStringRef)nsStr; 246 CFRelease(cfStr); // no-warning 247} 248 249@interface A; 250@end 251 252void check_bridge_to_non_cocoa(CFStringRef s) { 253 A *a = (__bridge_transfer A *) s; // no-crash 254} 255 256struct B; 257 258struct B * check_bridge_to_non_cf() { 259 NSString *s = [[NSString alloc] init]; 260 return (__bridge struct B*) s; 261} 262