1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-checker=deadcode -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-nonfragile-abi -fobjc-arc %s 2 3 typedef signed char BOOL; 4 typedef struct _NSZone NSZone; 5 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; 6 7 @protocol NSObject 8 - (BOOL)isEqual:(id)object; 9 @end 10 @protocol NSCopying 11 - (id)copyWithZone:(NSZone *)zone; 12 @end 13 @protocol NSCoding 14 - (void)encodeWithCoder:(NSCoder *)aCoder; 15 @end 16 @interface NSObject <NSObject> {} 17 + (id)alloc; 18 @end 19 typedef const struct __CFAllocator * CFAllocatorRef; 20 extern const CFAllocatorRef kCFAllocatorDefault; 21 typedef double CFTimeInterval; 22 typedef CFTimeInterval CFAbsoluteTime; 23 extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); 24 typedef const struct __CFDate * CFDateRef; 25 extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); 26 27 typedef const void* objc_objectptr_t; 28 __attribute__((ns_returns_retained)) id objc_retainedObject(objc_objectptr_t __attribute__((cf_consumed)) pointer); 29 __attribute__((ns_returns_not_retained)) id objc_unretainedObject(objc_objectptr_t pointer); 30 31 // Test the analyzer is working at all. 32 void test_working() { 33 int *p = 0; 34 *p = 0xDEADBEEF; // expected-warning {{null}} 35 } 36 37 // Test that in ARC mode that blocks are correctly automatically copied 38 // and not flagged as warnings by the analyzer. 39 typedef void (^Block)(void); 40 void testblock_bar(int x); 41 42 Block testblock_foo(int x) { 43 Block b = ^{ testblock_bar(x); }; 44 return b; // no-warning 45 } 46 47 Block testblock_baz(int x) { 48 return ^{ testblock_bar(x); }; // no-warning 49 } 50 51 Block global_block; 52 53 void testblock_qux(int x) { 54 global_block = ^{ testblock_bar(x); }; // no-warning 55 } 56 57 // Test that Objective-C pointers are null initialized. 58 void test_nil_initialized() { 59 id x; 60 if (x == 0) 61 return; 62 int *p = 0; 63 *p = 0xDEADBEEF; // no-warning 64 } 65 66 // Test that we don't flag leaks of Objective-C objects. 67 void test_alloc() { 68 [NSObject alloc]; // no-warning 69 } 70 71 // Test that CF allocations are still caught as leaks. 72 void test_cf_leak() { 73 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 74 CFDateRef date = CFDateCreate(0, t); // expected-warning {{Potential leak}} 75 (void) date; 76 } 77 78 // Test that 'init' methods do not try to claim ownerhip of an *unowned* allocated object 79 // in ARC mode. 80 @interface RDar9424890_A : NSObject 81 - (id)initWithCleaner:(int)pop mop:(NSString *)mop ; 82 - (RDar9424890_A *)rdar9424890:(NSString *)identifier; 83 @end 84 @interface RDar9424890_B : NSObject 85 @end 86 @implementation RDar9424890_B 87 - (RDar9424890_A *)obj:(RDar9424890_A *)obj { 88 static NSString *WhizFiz = @"WhizFiz"; 89 RDar9424890_A *cell = [obj rdar9424890:WhizFiz]; 90 if (cell == ((void*)0)) { 91 cell = [[RDar9424890_A alloc] initWithCleaner:0 mop:WhizFiz]; // no-warning 92 } 93 return cell; 94 } 95 @end 96 97 // Test that dead store checking works in the prescence of "cleanups" in the AST. 98 void rdar9424882() { 99 id x = [NSObject alloc]; // expected-warning {{Value stored to 'x' during its initialization is never read}} 100 } 101 102 // Test 103 typedef const void *CFTypeRef; 104 typedef const struct __CFString *CFStringRef; 105 106 @interface NSString 107 - (id) self; 108 @end 109 110 CFTypeRef CFCreateSomething(); 111 CFStringRef CFCreateString(); 112 CFTypeRef CFGetSomething(); 113 CFStringRef CFGetString(); 114 115 id CreateSomething(); 116 NSString *CreateNSString(); 117 118 void from_cf() { 119 id obj1 = (__bridge_transfer id)CFCreateSomething(); // expected-warning{{never read}} 120 id obj2 = (__bridge_transfer NSString*)CFCreateString(); 121 [obj2 self]; // Add a use, to show we can use the object after it has been transfered. 122 id obj3 = (__bridge id)CFGetSomething(); 123 [obj3 self]; // Add a use, to show we can use the object after it has been bridged. 124 id obj4 = (__bridge NSString*)CFGetString(); // expected-warning{{never read}} 125 id obj5 = (__bridge id)CFCreateSomething(); // expected-warning{{never read}} expected-warning{{leak}} 126 id obj6 = (__bridge NSString*)CFCreateString(); // expected-warning{{never read}} expected-warning{{leak}} 127 } 128 129 void to_cf(id obj) { 130 CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); // expected-warning{{never read}} 131 CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString(); // expected-warning{{never read}} 132 CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); // expected-warning{{never read}} 133 CFStringRef cf4 = (__bridge CFStringRef)CreateNSString(); // expected-warning{{never read}} 134 } 135 136 void test_objc_retainedObject() { 137 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 138 CFDateRef date = CFDateCreate(0, t); 139 id x = objc_retainedObject(date); 140 (void) x; 141 } 142 143 void test_objc_unretainedObject() { 144 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 145 CFDateRef date = CFDateCreate(0, t); // expected-warning {{Potential leak}} 146 id x = objc_unretainedObject(date); 147 (void) x; 148 } 149 150