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 | |
18 | void just_runloop() { // No warning: no statements in between |
19 | @autoreleasepool { |
20 | [[NSRunLoop mainRunLoop] run]; // no-warning |
21 | } |
22 | } |
23 | |
24 | void just_xpcmain() { // No warning: no statements in between |
25 | @autoreleasepool { |
26 | xpc_main(); // no-warning |
27 | } |
28 | } |
29 | |
30 | void runloop_init_before() { // 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 | |
38 | void runloop_init_before_separate_pool() { // 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 | |
49 | void xpcmain_init_before() { // 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 | |
57 | void runloop_init_before_two_objects() { // 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 | |
67 | void runloop_no_autoreleasepool() { |
68 | NSObject *object = [[NSObject alloc] init]; // no-warning |
69 | (void)object; |
70 | [[NSRunLoop mainRunLoop] run]; |
71 | } |
72 | |
73 | void runloop_init_after() { // 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 | |
81 | void no_crash_on_empty_children() { |
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 |
93 | int main() { |
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 |
103 | int main() { |
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 |
115 | int main() { |
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 |
124 | int main() { |
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))) |
136 | typedef const CF_BRIDGED_TYPE(id) void * CFTypeRef; |
137 | typedef const struct CF_BRIDGED_TYPE(NSString) __CFString * CFStringRef; |
138 | |
139 | typedef enum { WARNING } Level; |
140 | id do_log(Level, const char *); |
141 | #define log(level, msg) __extension__({ (do_log(level, msg)); }) |
142 | |
143 | @interface I |
144 | - foo; |
145 | @end |
146 | |
147 | CFStringRef processString(const __NSConstantString *, void *); |
148 | |
149 | #define CFSTR __builtin___CFStringMakeConstantString |
150 | |
151 | int main() { |
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 | |