1 | // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fobjc-arc -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text |
2 | // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text |
3 | |
4 | typedef __typeof(sizeof(int)) size_t; |
5 | |
6 | #define HAS_ARC __has_feature(objc_arc) |
7 | |
8 | typedef unsigned long long CFOptionFlags; |
9 | typedef signed long long CFIndex; |
10 | |
11 | typedef CFIndex CFPropertyListFormat; enum { |
12 | kCFPropertyListOpenStepFormat = 1, |
13 | kCFPropertyListXMLFormat_v1_0 = 100, |
14 | kCFPropertyListBinaryFormat_v1_0 = 200 |
15 | }; |
16 | |
17 | typedef const struct __CFAllocator * CFAllocatorRef; |
18 | extern const CFAllocatorRef kCFAllocatorDefault; |
19 | typedef struct __CFDictionary * CFDictionaryRef; |
20 | typedef struct __CFError * CFErrorRef; |
21 | typedef struct __CFDataRef * CFDataRef; |
22 | typedef void * CFPropertyListRef; |
23 | |
24 | CFPropertyListRef CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags options, CFPropertyListFormat *format, CFErrorRef *error); |
25 | |
26 | typedef signed char BOOL; |
27 | typedef struct _NSZone NSZone; |
28 | @class NSDictionary; |
29 | @class NSData; |
30 | @class NSString; |
31 | |
32 | @protocol NSObject |
33 | - (BOOL)isEqual:(id)object; |
34 | - (id)retain; |
35 | - (oneway void)release; |
36 | - (id)autorelease; |
37 | - (NSString *)description; |
38 | - (id)init; |
39 | @end |
40 | @interface NSObject <NSObject> {} |
41 | + (id)allocWithZone:(NSZone *)zone; |
42 | + (id)alloc; |
43 | + (id)new; |
44 | - (void)dealloc; |
45 | @end |
46 | |
47 | @interface NSDictionary : NSObject |
48 | @end |
49 | |
50 | #define OS_OBJECT_RETURNS_RETAINED __attribute__((__ns_returns_retained__)) |
51 | #define DISPATCH_RETURNS_RETAINED OS_OBJECT_RETURNS_RETAINED |
52 | |
53 | @protocol OS_dispatch_object |
54 | @end |
55 | @protocol OS_dispatch_data <OS_dispatch_object> |
56 | @end |
57 | @protocol OS_dispatch_queue <OS_dispatch_object> |
58 | @end |
59 | |
60 | typedef NSObject<OS_dispatch_object> *dispatch_object_t; |
61 | typedef NSObject<OS_dispatch_data> *dispatch_data_t; |
62 | typedef NSObject<OS_dispatch_queue> *dispatch_queue_t; |
63 | |
64 | typedef void (^dispatch_block_t)(void); |
65 | |
66 | dispatch_queue_t dispatch_get_main_queue(void); |
67 | |
68 | DISPATCH_RETURNS_RETAINED dispatch_data_t |
69 | dispatch_data_create(const void *buffer, size_t size, |
70 | dispatch_queue_t _Nullable queue, |
71 | dispatch_block_t _Nullable destructor); |
72 | |
73 | void _dispatch_object_validate(dispatch_object_t object); |
74 | |
75 | #define dispatch_retain(object) \ |
76 | __extension__({ dispatch_object_t _o = (object); \ |
77 | _dispatch_object_validate(_o); \ |
78 | (void)[_o retain]; }) |
79 | #define dispatch_release(object) \ |
80 | __extension__({ dispatch_object_t _o = (object); \ |
81 | _dispatch_object_validate(_o); \ |
82 | [_o release]; }) |
83 | |
84 | |
85 | @interface SomeClass |
86 | @end |
87 | |
88 | @implementation SomeClass |
89 | - (NSDictionary *)copyTestWithBridgeReturningRetainable:(NSData *)plistData { |
90 | CFErrorRef error; |
91 | CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error); |
92 | #if HAS_ARC |
93 | // expected-note@-2 {{Call to function 'CFPropertyListCreateWithData' returns a Core Foundation object of type 'CFPropertyListRef' with a +1 retain count}} |
94 | #endif |
95 | return (__bridge NSDictionary *)testDict; |
96 | #if HAS_ARC |
97 | // expected-warning@-2 {{Potential leak of an object stored into 'testDict'}} |
98 | // expected-note@-3 {{Object leaked: object allocated and stored into 'testDict' is returned from a method managed by Automatic Reference Counting}} |
99 | #endif |
100 | } |
101 | |
102 | - (NSDictionary *)copyTestWithoutBridgeReturningRetainable:(NSData *)plistData { |
103 | NSDictionary *testDict = [[NSDictionary alloc] init]; |
104 | return testDict; // no-warning |
105 | } |
106 | |
107 | - (NSDictionary *)copyTestWithBridgeTransferReturningRetainable:(NSData *)plistData { |
108 | CFErrorRef error; |
109 | CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error); |
110 | return (__bridge_transfer NSDictionary *)testDict; // no-warning under ARC |
111 | #if !HAS_ARC |
112 | // expected-warning@-2 {{'__bridge_transfer' casts have no effect when not using ARC}} // Warning from Sema |
113 | #endif |
114 | } |
115 | |
116 | - (CFDictionaryRef)copyTestReturningCoreFoundation:(NSData *)plistData { |
117 | CFErrorRef error; |
118 | CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error); |
119 | return testDict; |
120 | } |
121 | @end |
122 | |
123 | int buf[1024]; |
124 | |
125 | void libdispatch_leaked_data() { |
126 | dispatch_data_t data = dispatch_data_create(buf, 1024, |
127 | dispatch_get_main_queue(), ^{}); |
128 | } |
129 | #if !HAS_ARC |
130 | // expected-warning@-2{{Potential leak of an object stored into 'data'}} |
131 | // expected-note@-5{{Call to function 'dispatch_data_create' returns an Objective-C object with a +1 retain count}} |
132 | // expected-note@-4{{Object leaked: object allocated and stored into 'data' is not referenced later in this execution path and has a retain count of +1}} |
133 | #endif |
134 | |
135 | void libdispatch_dispatch_released_data() { |
136 | dispatch_data_t data = dispatch_data_create(buf, 1024, |
137 | dispatch_get_main_queue(), ^{}); |
138 | #if !HAS_ARC |
139 | dispatch_release(data); // no-warning |
140 | #endif |
141 | } |
142 | |
143 | void libdispatch_objc_released_data() { |
144 | dispatch_data_t data = dispatch_data_create(buf, 1024, |
145 | dispatch_get_main_queue(), ^{}); |
146 | #if !HAS_ARC |
147 | [data release]; // no-warning |
148 | #endif |
149 | } |
150 | |
151 | void libdispatch_leaked_retained_data() { |
152 | dispatch_data_t data = dispatch_data_create(buf, 1024, |
153 | dispatch_get_main_queue(), ^{}); |
154 | #if !HAS_ARC |
155 | dispatch_retain(data); |
156 | [data release]; |
157 | #endif |
158 | } |
159 | #if !HAS_ARC |
160 | // expected-warning@-2{{Potential leak of an object stored into 'data'}} |
161 | // expected-note@-9{{Call to function 'dispatch_data_create' returns an Objective-C object with a +1 retain count}} |
162 | // expected-note@-7{{Reference count incremented. The object now has a +2 retain count}} |
163 | // expected-note@-7{{Reference count decremented. The object now has a +1 retain count}} |
164 | // expected-note@-6{{Object leaked: object allocated and stored into 'data' is not referenced later in this execution path and has a retain count of +1}} |
165 | #endif |
166 | |