1// RUN: %clang_analyze_cc1 -fobjc-arc -triple x86_64-darwin\ 2// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s 3// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP1=1 -fobjc-arc -triple x86_64-darwin\ 4// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s 5// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP2=1 -fobjc-arc -triple x86_64-darwin\ 6// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s 7// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP3=1 -fobjc-arc -triple x86_64-darwin\ 8// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s 9// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP4=1 -fobjc-arc -triple x86_64-darwin\ 10// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s 11// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP5=1 -fobjc-arc -triple x86_64-darwin\ 12// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s 13 14#include "../Inputs/system-header-simulator-for-objc-dealloc.h" 15 16#ifndef EXTRA 17 18void just_runloop(void) { // No warning: no statements in between 19 @autoreleasepool { 20 [[NSRunLoop mainRunLoop] run]; // no-warning 21 } 22} 23 24void just_xpcmain(void) { // No warning: no statements in between 25 @autoreleasepool { 26 xpc_main(); // no-warning 27 } 28} 29 30void runloop_init_before(void) { // Warning: object created before the loop. 31 @autoreleasepool { 32 NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool followed by the launch of main run loop may never get released; consider moving them to a separate autorelease pool}} 33 (void) object; 34 [[NSRunLoop mainRunLoop] run]; 35 } 36} 37 38void runloop_init_before_separate_pool(void) { // No warning: separate autorelease pool. 39 @autoreleasepool { 40 NSObject *object; 41 @autoreleasepool { 42 object = [[NSObject alloc] init]; // no-warning 43 } 44 (void) object; 45 [[NSRunLoop mainRunLoop] run]; 46 } 47} 48 49void xpcmain_init_before(void) { // Warning: object created before the loop. 50 @autoreleasepool { 51 NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool followed by the launch of xpc_main may never get released; consider moving them to a separate autorelease pool}} 52 (void) object; 53 xpc_main(); 54 } 55} 56 57void runloop_init_before_two_objects(void) { // Warning: object created before the loop. 58 @autoreleasepool { 59 NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool followed by the launch of main run loop may never get released; consider moving them to a separate autorelease pool}} 60 NSObject *object2 = [[NSObject alloc] init]; // no-warning, warning on the first one is enough. 61 (void) object; 62 (void) object2; 63 [[NSRunLoop mainRunLoop] run]; 64 } 65} 66 67void runloop_no_autoreleasepool(void) { 68 NSObject *object = [[NSObject alloc] init]; // no-warning 69 (void)object; 70 [[NSRunLoop mainRunLoop] run]; 71} 72 73void runloop_init_after(void) { // No warning: objects created after the loop 74 @autoreleasepool { 75 [[NSRunLoop mainRunLoop] run]; 76 NSObject *object = [[NSObject alloc] init]; // no-warning 77 (void) object; 78 } 79} 80 81void no_crash_on_empty_children(void) { 82 @autoreleasepool { 83 for (;;) {} 84 NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool followed by the launch of main run loop may never get released; consider moving them to a separate autorelease pool}} 85 [[NSRunLoop mainRunLoop] run]; 86 (void) object; 87 } 88} 89 90#endif 91 92#ifdef AP1 93int main(void) { 94 NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool of last resort followed by the launch of main run loop may never get released; consider moving them to a separate autorelease pool}} 95 (void) object; 96 [[NSRunLoop mainRunLoop] run]; 97 return 0; 98} 99#endif 100 101#ifdef AP2 102// expected-no-diagnostics 103int main(void) { 104 NSObject *object = [[NSObject alloc] init]; // no-warning 105 (void) object; 106 @autoreleasepool { 107 [[NSRunLoop mainRunLoop] run]; 108 } 109 return 0; 110} 111#endif 112 113#ifdef AP3 114// expected-no-diagnostics 115int main(void) { 116 [[NSRunLoop mainRunLoop] run]; 117 NSObject *object = [[NSObject alloc] init]; // no-warning 118 (void) object; 119 return 0; 120} 121#endif 122 123#ifdef AP4 124int main(void) { 125 NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool of last resort followed by the launch of xpc_main may never get released; consider moving them to a separate autorelease pool}} 126 (void) object; 127 xpc_main(); 128 return 0; 129} 130#endif 131 132#ifdef AP5 133@class NSString; 134@class NSConstantString; 135#define CF_BRIDGED_TYPE(T) __attribute__((objc_bridge(T))) 136typedef const CF_BRIDGED_TYPE(id) void * CFTypeRef; 137typedef const struct CF_BRIDGED_TYPE(NSString) __CFString * CFStringRef; 138 139typedef enum { WARNING } Level; 140id do_log(Level, const char *); 141#define log(level, msg) __extension__({ (do_log(level, msg)); }) 142 143@interface I 144- foo; 145@end 146 147CFStringRef processString(const __NSConstantString *, void *); 148 149#define CFSTR __builtin___CFStringMakeConstantString 150 151int main(void) { 152 I *i; 153 @autoreleasepool { 154 NSString *s1 = (__bridge_transfer NSString *)processString(0, 0); 155 NSString *s2 = (__bridge_transfer NSString *)processString((CFSTR("")), ((void *)0)); 156 log(WARNING, "Hello world!"); 157 } 158 [[NSRunLoop mainRunLoop] run]; 159 [i foo]; // no-crash // expected-warning{{Temporary objects allocated in the autorelease pool of last resort followed by the launch of main run loop may never get released; consider moving them to a separate autorelease pool}} 160} 161#endif 162