1 // UNSUPPORTED: system-windows
2 // RUN: %clang_analyze_cc1 -DARC -fobjc-arc -analyzer-checker=core,osx.cocoa.AutoreleaseWrite %s -triple x86_64-darwin -fblocks -verify
3 // RUN: %clang_analyze_cc1 -DNOARC -analyzer-checker=core,osx.cocoa.AutoreleaseWrite %s -fblocks -triple x86_64-darwin -verify
6 typedef signed char BOOL;
8 @protocol NSObject - (BOOL)isEqual:(id)object; @end
9 @interface NSObject <NSObject> {}
18 typedef unsigned long NSUInteger;
20 @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
21 @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
22 @interface NSError : NSObject <NSCopying, NSCoding> {}
23 + (id)errorWithDomain:(int)domain;
26 typedef int dispatch_semaphore_t;
27 typedef void (^block_t)();
30 NSEnumerationConcurrent = (1UL << 0),
31 NSEnumerationReverse = (1UL << 1)
32 } NSEnumerationOptions;
35 - (void)enumerateObjectsUsingBlock:(block_t)block;
39 - (void)objectsPassingTest:(block_t)block;
42 @interface NSDictionary
43 - (void)enumerateKeysAndObjectsUsingBlock:(block_t)block;
47 - (void)indexesPassingTest:(block_t)block;
48 - (NSUInteger)indexWithOptions:(NSEnumerationOptions)opts
49 passingTest:(BOOL (^)(NSUInteger idx, BOOL *stop))predicate;
53 typedef struct dispatch_queue_s *dispatch_queue_t;
54 typedef void (^dispatch_block_t)(void);
55 extern dispatch_queue_t queue;
57 void dispatch_group_async(dispatch_queue_t queue,
59 dispatch_block_t block);
60 void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
61 dispatch_semaphore_t dispatch_semaphore_create(int);
63 void dispatch_semaphore_wait(dispatch_semaphore_t, int);
64 void dispatch_semaphore_signal(dispatch_semaphore_t);
66 // No warnings without ARC.
69 // expected-no-diagnostics
70 BOOL writeToErrorWithIterator(NSError ** error, NSArray *a) {
71 [a enumerateObjectsUsingBlock:^{
72 *error = [NSError errorWithDomain:1]; // no-warning
79 @interface I : NSObject
80 - (BOOL) writeToStrongErrorInBlock:(NSError *__strong *)error;
81 - (BOOL) writeToErrorInBlock:(NSError *__autoreleasing *)error;
82 - (BOOL) writeToLocalErrorInBlock:(NSError **)error;
83 - (BOOL) writeToErrorInBlockMultipleTimes:(NSError *__autoreleasing *)error;
84 - (BOOL) writeToError:(NSError *__autoreleasing *)error;
85 - (BOOL) writeToErrorWithDispatchGroup:(NSError *__autoreleasing *)error;
86 - (BOOL)writeToErrorInAutoreleasePool:(NSError *__autoreleasing *)error;
87 - (BOOL)writeToStrongErrorInAutoreleasePool:(NSError *__strong *)error;
88 - (BOOL)writeToLocalErrorInAutoreleasePool:(NSError *__autoreleasing *)error;
89 - (BOOL)writeToErrorInAutoreleasePoolMultipleTimes:(NSError *__autoreleasing *)error;
94 - (BOOL) writeToErrorInBlock:(NSError *__autoreleasing *)error {
95 dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
96 dispatch_async(queue, ^{
98 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before method returns; consider writing first to a strong local variable declared outside of the block}}
100 dispatch_semaphore_signal(sem);
103 dispatch_semaphore_wait(sem, 100);
107 - (BOOL) writeToErrorWithDispatchGroup:(NSError *__autoreleasing *)error {
108 dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
109 dispatch_group_async(queue, 0, ^{
111 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before method returns; consider writing first to a strong local variable declared outside of the block}}
113 dispatch_semaphore_signal(sem);
116 dispatch_semaphore_wait(sem, 100);
120 - (BOOL) writeToLocalErrorInBlock:(NSError *__autoreleasing *)error {
121 dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
122 dispatch_async(queue, ^{
124 NSError*__strong* error3 = &error2;
126 *error3 = [NSError errorWithDomain:1]; // no-warning
128 dispatch_semaphore_signal(sem);
131 dispatch_semaphore_wait(sem, 100);
135 - (BOOL) writeToStrongErrorInBlock:(NSError *__strong *)error {
136 dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
137 dispatch_async(queue, ^{
139 *error = [NSError errorWithDomain:2]; // no-warning
141 dispatch_semaphore_signal(sem);
144 dispatch_semaphore_wait(sem, 100);
148 - (BOOL) writeToErrorInBlockMultipleTimes:(NSError *__autoreleasing *)error {
149 dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
150 dispatch_async(queue, ^{
152 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before method returns; consider writing first to a strong local variable declared outside of the block}}
154 dispatch_semaphore_signal(sem);
156 dispatch_async(queue, ^{
158 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before method returns; consider writing first to a strong local variable declared outside of the block}}
159 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before method returns; consider writing first to a strong local variable declared outside of the block}}
161 dispatch_semaphore_signal(sem);
163 *error = [NSError errorWithDomain:1]; // no-warning
165 dispatch_semaphore_wait(sem, 100);
169 - (BOOL)writeToErrorInAutoreleasePool:(NSError *__autoreleasing *)error {
172 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside locally-scoped autorelease pool; consider writing first to a strong local variable declared outside of the autorelease pool}}
179 - (BOOL)writeToStrongErrorInAutoreleasePool:(NSError *__strong *)error {
182 *error = [NSError errorWithDomain:1]; // no-warning
189 - (BOOL)writeToLocalErrorInAutoreleasePool:(NSError *__autoreleasing *)error {
192 localError = [NSError errorWithDomain:1]; // no-warning
196 *error = localError; // no-warning
202 - (BOOL)writeToErrorInAutoreleasePoolMultipleTimes:(NSError *__autoreleasing *)error {
205 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside locally-scoped autorelease pool; consider writing first to a strong local variable declared outside of the autorelease pool}}
209 *error = [NSError errorWithDomain:1]; // no-warning
213 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside locally-scoped autorelease pool; consider writing first to a strong local variable declared outside of the autorelease pool}}
214 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside locally-scoped autorelease pool; consider writing first to a strong local variable declared outside of the autorelease pool}}
221 - (BOOL) writeToError:(NSError *__autoreleasing *)error {
222 *error = [NSError errorWithDomain:1]; // no-warning
227 BOOL writeToErrorInBlockFromCFunc(NSError *__autoreleasing* error) {
228 dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
229 dispatch_async(queue, ^{
231 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
233 dispatch_semaphore_signal(sem);
236 dispatch_semaphore_wait(sem, 100);
240 BOOL writeIntoErrorInAutoreleasePoolFromCFunc(NSError *__autoreleasing *error) {
243 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside locally-scoped autorelease pool; consider writing first to a strong local variable declared outside of the autorelease pool}}
249 BOOL writeToErrorNoWarning(NSError *__autoreleasing* error) {
250 *error = [NSError errorWithDomain:1]; // no-warning
254 BOOL writeToErrorWithIterator(NSError *__autoreleasing* error, NSArray *a, NSSet *s, NSDictionary *d, NSIndexSet *i) { [a enumerateObjectsUsingBlock:^{
255 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
257 [d enumerateKeysAndObjectsUsingBlock:^{
258 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
260 [s objectsPassingTest:^{
261 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
263 [i indexesPassingTest:^{
264 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
266 [i indexWithOptions: NSEnumerationReverse passingTest:^(NSUInteger idx, BOOL *stop) {
267 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
273 void writeIntoError(NSError **error) {
274 *error = [NSError errorWithDomain:1];
277 extern void readError(NSError *error);
279 void writeToErrorWithIteratorNonnull(NSError *__autoreleasing* _Nonnull error, NSDictionary *a) {
280 [a enumerateKeysAndObjectsUsingBlock:^{
281 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter}}
286 void escapeErrorFromIterator(NSError *__autoreleasing* _Nonnull error, NSDictionary *a) {
287 [a enumerateKeysAndObjectsUsingBlock:^{
288 writeIntoError(error); // expected-warning{{Capture of autoreleasing out parameter}}
292 void noWarningOnRead(NSError *__autoreleasing* error, NSDictionary *a) {
293 [a enumerateKeysAndObjectsUsingBlock:^{
294 NSError* local = *error; // no-warning
298 void noWarningOnEscapeRead(NSError *__autoreleasing* error, NSDictionary *a) {
299 [a enumerateKeysAndObjectsUsingBlock:^{
300 readError(*error); // no-warning
304 @interface ErrorCapture
305 - (void) captureErrorOut:(NSError**) error;
306 - (void) captureError:(NSError*) error;
309 void escapeErrorFromIteratorMethod(NSError *__autoreleasing* _Nonnull error,
311 ErrorCapture *capturer) {
312 [a enumerateKeysAndObjectsUsingBlock:^{
313 [capturer captureErrorOut:error]; // expected-warning{{Capture of autoreleasing out parameter}}
317 void noWarningOnEscapeReadMethod(NSError *__autoreleasing* error,
319 ErrorCapture *capturer) {
320 [a enumerateKeysAndObjectsUsingBlock:^{
321 [capturer captureError:*error]; // no-warning
325 void multipleErrors(NSError *__autoreleasing* error, NSDictionary *a) {
326 [a enumerateKeysAndObjectsUsingBlock:^{
327 writeIntoError(error); // expected-warning{{Capture of autoreleasing out parameter}}
328 *error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter}}
329 writeIntoError(error); // expected-warning{{Capture of autoreleasing out parameter}}
333 typedef void (^errBlock)(NSError *__autoreleasing *error);
335 extern void expectError(errBlock);
337 void captureAutoreleasingVarFromBlock(NSDictionary *dict) {
338 expectError(^(NSError *__autoreleasing *err) {
339 [dict enumerateKeysAndObjectsUsingBlock:^{
340 writeIntoError(err); // expected-warning{{Capture of autoreleasing out parameter 'err'}}