1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.performance.GCDAntipattern %s -fblocks -verify
2 typedef signed char BOOL;
3 @protocol NSObject - (BOOL)isEqual:(id)object; @end
4 @interface NSObject <NSObject> {}
12 typedef int dispatch_semaphore_t;
13 typedef int dispatch_group_t;
14 typedef void (^block_t)(void);
16 dispatch_semaphore_t dispatch_semaphore_create(int);
17 dispatch_group_t dispatch_group_create(void);
18 void dispatch_group_enter(dispatch_group_t);
19 void dispatch_group_leave(dispatch_group_t);
20 void dispatch_group_wait(dispatch_group_t, int);
23 void dispatch_semaphore_wait(dispatch_semaphore_t, int);
24 void dispatch_semaphore_signal(dispatch_semaphore_t);
26 void func(void (^)(void));
27 void func_w_typedef(block_t);
31 void use_semaphor_antipattern(void) {
32 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
35 dispatch_semaphore_signal(sema);
37 dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
40 // It's OK to use pattern in tests.
41 // We simply match the containing function name against ^test.
42 void test_no_warning(void) {
43 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
46 dispatch_semaphore_signal(sema);
48 dispatch_semaphore_wait(sema, 100);
51 void use_semaphor_antipattern_multiple_times(void) {
52 dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
55 dispatch_semaphore_signal(sema1);
57 dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}
59 dispatch_semaphore_t sema2 = dispatch_semaphore_create(0);
62 dispatch_semaphore_signal(sema2);
64 dispatch_semaphore_wait(sema2, 100); // expected-warning{{Waiting on a callback using a semaphore}}
67 void use_semaphor_antipattern_multiple_wait(void) {
68 dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
71 dispatch_semaphore_signal(sema1);
73 // FIXME: multiple waits on same semaphor should not raise a warning.
74 dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}
75 dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}
78 void warn_incorrect_order(void) {
79 // FIXME: ASTMatchers do not allow ordered matching, so would match even
81 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
83 dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}
85 dispatch_semaphore_signal(sema);
89 void warn_w_typedef(void) {
90 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
93 dispatch_semaphore_signal(sema);
95 dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
98 void warn_nested_ast(void) {
99 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
103 dispatch_semaphore_signal(sema);
107 dispatch_semaphore_signal(sema);
110 dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
113 void use_semaphore_assignment(void) {
114 dispatch_semaphore_t sema;
115 sema = dispatch_semaphore_create(0);
118 dispatch_semaphore_signal(sema);
120 dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
123 void use_semaphore_assignment_init(void) {
124 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
125 sema = dispatch_semaphore_create(1);
128 dispatch_semaphore_signal(sema);
130 dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
133 void differentsemaphoreok(void) {
134 dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
135 dispatch_semaphore_t sema2 = dispatch_semaphore_create(0);
138 dispatch_semaphore_signal(sema1);
140 dispatch_semaphore_wait(sema2, 100); // no-warning
143 void nosignalok(void) {
144 dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
145 dispatch_semaphore_wait(sema1, 100);
148 void nowaitok(void) {
149 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
151 dispatch_semaphore_signal(sema);
155 void noblockok(void) {
156 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
157 dispatch_semaphore_signal(sema);
158 dispatch_semaphore_wait(sema, 100);
161 void storedblockok(void) {
162 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
164 dispatch_semaphore_signal(sema);
166 dispatch_semaphore_wait(sema, 100);
169 void passed_semaphore_ok(dispatch_semaphore_t sema) {
171 dispatch_semaphore_signal(sema);
173 dispatch_semaphore_wait(sema, 100);
176 void warn_with_cast(void) {
177 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
180 dispatch_semaphore_signal((int)sema);
182 dispatch_semaphore_wait((int)sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
185 @interface MyInterface1 : NSObject
186 -(void)use_method_warn;
187 -(void) pass_block_as_second_param_warn;
188 -(void)use_objc_callback_warn;
189 -(void) use_dispatch_group;
191 -(void)acceptBlock:(block_t)callback;
192 -(void)flag:(int)flag acceptBlock:(block_t)callback;
195 @implementation MyInterface1
197 -(void)use_method_warn {
198 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
201 dispatch_semaphore_signal(sema);
203 dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}
206 -(void) pass_block_as_second_param_warn {
207 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
209 [self flag:1 acceptBlock:^{
210 dispatch_semaphore_signal(sema);
212 dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}
216 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
219 dispatch_semaphore_signal(sema);
221 dispatch_semaphore_wait(sema, 100);
224 -(void)acceptBlock:(block_t) callback {
228 -(void)flag:(int)flag acceptBlock:(block_t)callback {
232 -(void)use_objc_callback_warn {
233 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
236 dispatch_semaphore_signal(sema);
238 dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}
241 -(void)use_dispatch_group {
242 dispatch_group_t group = dispatch_group_create();
243 dispatch_group_enter(group);
245 dispatch_group_leave(group);
247 dispatch_group_wait(group, 100); // expected-warning{{Waiting on a callback using a group}}
251 void use_objc_and_c_callback(MyInterface1 *t) {
252 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
255 dispatch_semaphore_signal(sema);
257 dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
259 dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
262 dispatch_semaphore_signal(sema1);
264 dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback}}
268 // No warnings: class name contains "test"
269 @interface Test1 : NSObject
270 -(void)use_method_warn;
273 @implementation Test1
274 -(void)use_method_warn {
275 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
278 dispatch_semaphore_signal(sema);
280 dispatch_semaphore_wait(sema, 100);
285 // No warnings: class name contains "mock"
286 @interface Mock1 : NSObject
287 -(void)use_method_warn;
290 @implementation Mock1
291 -(void)use_method_warn {
292 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
295 dispatch_semaphore_signal(sema);
297 dispatch_semaphore_wait(sema, 100);
301 void dispatch_group_wait_func(MyInterface1 *M) {
302 dispatch_group_t group = dispatch_group_create();
303 dispatch_group_enter(group);
306 dispatch_group_leave(group);
308 dispatch_group_wait(group, 100); // expected-warning{{Waiting on a callback using a group}}
312 void dispatch_group_wait_cfunc(MyInterface1 *M) {
313 dispatch_group_t group = dispatch_group_create();
314 dispatch_group_enter(group);
316 dispatch_group_leave(group);
318 dispatch_group_wait(group, 100); // expected-warning{{Waiting on a callback using a group}}
321 void dispatch_group_and_semaphore_use(MyInterface1 *M) {
322 dispatch_group_t group = dispatch_group_create();
323 dispatch_group_enter(group);
325 dispatch_group_leave(group);
327 dispatch_group_wait(group, 100); // expected-warning{{Waiting on a callback using a group}}
329 dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
332 dispatch_semaphore_signal(sema1);
334 dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}
337 void no_warn_on_nonzero_semaphore(MyInterface1 *M) {
338 dispatch_semaphore_t sema1 = dispatch_semaphore_create(1);
341 dispatch_semaphore_signal(sema1);
343 dispatch_semaphore_wait(sema1, 100); // no-warning