blob: b02af0515186012336d76c9857fa1df72c0b7cc0 [file] [log] [blame]
John McCalld1e40d52011-10-02 01:16:38 +00001// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,deadcode -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-arc %s
John McCallf85e1932011-06-15 23:02:42 +00002
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
Ted Kremenek05a46522011-08-27 21:15:48 +0000150// Previously this resulted in a "return of stack address" warning.
151id test_return() {
152 id x = (__bridge_transfer id) CFCreateString();
153 return x; // no-warning
154}
155