[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Analysis / gcdantipatternchecker_test.m
blob1d7ecfc1aca930e98c470d00ede434e517958960
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> {}
5 +(id)alloc;
6 -(id)init;
7 -(id)autorelease;
8 -(id)copy;
9 -(id)retain;
10 @end
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);
29 int coin(void);
31 void use_semaphor_antipattern(void) {
32   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
34   func(^{
35       dispatch_semaphore_signal(sema);
36   });
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);
45   func(^{
46       dispatch_semaphore_signal(sema);
47   });
48   dispatch_semaphore_wait(sema, 100);
51 void use_semaphor_antipattern_multiple_times(void) {
52   dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
54   func(^{
55       dispatch_semaphore_signal(sema1);
56   });
57   dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}
59   dispatch_semaphore_t sema2 = dispatch_semaphore_create(0);
61   func(^{
62       dispatch_semaphore_signal(sema2);
63   });
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);
70   func(^{
71       dispatch_semaphore_signal(sema1);
72   });
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
80   // if out of order.
81   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
83   dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}
84   func(^{
85       dispatch_semaphore_signal(sema);
86   });
89 void warn_w_typedef(void) {
90   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
92   func_w_typedef(^{
93       dispatch_semaphore_signal(sema);
94   });
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);
101   if (coin()) {
102     func(^{
103          dispatch_semaphore_signal(sema);
104          });
105   } else {
106     func(^{
107          dispatch_semaphore_signal(sema);
108          });
109   }
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);
117   func(^{
118       dispatch_semaphore_signal(sema);
119   });
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);
127   func(^{
128       dispatch_semaphore_signal(sema);
129   });
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);
137   func(^{
138       dispatch_semaphore_signal(sema1);
139   });
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);
150   func(^{
151       dispatch_semaphore_signal(sema);
152   });
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);
163   block_t b = ^{
164       dispatch_semaphore_signal(sema);
165   };
166   dispatch_semaphore_wait(sema, 100);
169 void passed_semaphore_ok(dispatch_semaphore_t sema) {
170   func(^{
171       dispatch_semaphore_signal(sema);
172   });
173   dispatch_semaphore_wait(sema, 100);
176 void warn_with_cast(void) {
177   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
179   func(^{
180       dispatch_semaphore_signal((int)sema);
181   });
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;
190 -(void)testNoWarn;
191 -(void)acceptBlock:(block_t)callback;
192 -(void)flag:(int)flag acceptBlock:(block_t)callback;
193 @end
195 @implementation MyInterface1
197 -(void)use_method_warn {
198   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
200   func(^{
201       dispatch_semaphore_signal(sema);
202   });
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);
211   }];
212   dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}
215 -(void)testNoWarn {
216   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
218   func(^{
219       dispatch_semaphore_signal(sema);
220   });
221   dispatch_semaphore_wait(sema, 100);
224 -(void)acceptBlock:(block_t) callback {
225   callback();
228 -(void)flag:(int)flag acceptBlock:(block_t)callback {
229   callback();
232 -(void)use_objc_callback_warn {
233   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
235   [self acceptBlock:^{
236       dispatch_semaphore_signal(sema);
237   }];
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);
244   [self acceptBlock:^{
245     dispatch_group_leave(group);
246   }];
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);
254   func(^{
255       dispatch_semaphore_signal(sema);
256   });
257   dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
259   dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
261   [t acceptBlock:^{
262       dispatch_semaphore_signal(sema1);
263   }];
264   dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback}}
266 @end
268 // No warnings: class name contains "test"
269 @interface Test1 : NSObject
270 -(void)use_method_warn;
271 @end
273 @implementation Test1
274 -(void)use_method_warn {
275   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
277   func(^{
278       dispatch_semaphore_signal(sema);
279   });
280   dispatch_semaphore_wait(sema, 100);
282 @end
285 // No warnings: class name contains "mock"
286 @interface Mock1 : NSObject
287 -(void)use_method_warn;
288 @end
290 @implementation Mock1
291 -(void)use_method_warn {
292   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
294   func(^{
295       dispatch_semaphore_signal(sema);
296   });
297   dispatch_semaphore_wait(sema, 100);
299 @end
301 void dispatch_group_wait_func(MyInterface1 *M) {
302   dispatch_group_t group = dispatch_group_create();
303   dispatch_group_enter(group);
305   func(^{
306       dispatch_group_leave(group);
307   });
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);
315   [M acceptBlock:^{
316     dispatch_group_leave(group);
317   }];
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);
324   [M acceptBlock:^{
325     dispatch_group_leave(group);
326   }];
327   dispatch_group_wait(group, 100); // expected-warning{{Waiting on a callback using a group}}
329   dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
331   [M acceptBlock:^{
332       dispatch_semaphore_signal(sema1);
333   }];
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);
340   [M acceptBlock:^{
341       dispatch_semaphore_signal(sema1);
342   }];
343   dispatch_semaphore_wait(sema1, 100); // no-warning