objc-arc.m revision f85e193739c953358c865005855253af4f68a497
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
3typedef signed char BOOL;
4typedef 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
19typedef const struct __CFAllocator * CFAllocatorRef;
20extern const CFAllocatorRef kCFAllocatorDefault;
21typedef double CFTimeInterval;
22typedef CFTimeInterval CFAbsoluteTime;
23extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
24typedef const struct __CFDate * CFDateRef;
25extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
26
27typedef 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.
32void 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.
39typedef void (^Block)(void);
40void testblock_bar(int x);
41
42Block testblock_foo(int x) {
43  Block b = ^{ testblock_bar(x); };
44  return b; // no-warning
45}
46
47Block testblock_baz(int x) {
48  return ^{ testblock_bar(x); }; // no-warning
49}
50
51Block global_block;
52
53void testblock_qux(int x) {
54  global_block = ^{ testblock_bar(x); }; // no-warning
55}
56
57// Test that Objective-C pointers are null initialized.
58void 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.
67void test_alloc() {
68  [NSObject alloc]; // no-warning
69}
70
71// Test that CF allocations are still caught as leaks.
72void 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.
98void rdar9424882() {
99  id x = [NSObject alloc]; // expected-warning {{Value stored to 'x' during its initialization is never read}}
100}
101
102// Test 
103typedef const void *CFTypeRef;
104typedef const struct __CFString *CFStringRef;
105
106@interface NSString
107- (id) self;
108@end
109
110CFTypeRef CFCreateSomething();
111CFStringRef CFCreateString();
112CFTypeRef CFGetSomething();
113CFStringRef CFGetString();
114
115id CreateSomething();
116NSString *CreateNSString();
117
118void 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
129void 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
136void test_objc_retainedObject() {
137  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
138  CFDateRef date = CFDateCreate(0, t);
139  id x = objc_retainedObject(date);
140  (void) x;
141}
142
143void 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