brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.0 KiB · 1d7ecfc Raw
346 lines · plain
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.performance.GCDAntipattern %s -fblocks -verify2typedef signed char BOOL;3@protocol NSObject  - (BOOL)isEqual:(id)object; @end4@interface NSObject <NSObject> {}5+(id)alloc;6-(id)init;7-(id)autorelease;8-(id)copy;9-(id)retain;10@end11 12typedef int dispatch_semaphore_t;13typedef int dispatch_group_t;14typedef void (^block_t)(void);15 16dispatch_semaphore_t dispatch_semaphore_create(int);17dispatch_group_t dispatch_group_create(void);18void dispatch_group_enter(dispatch_group_t);19void dispatch_group_leave(dispatch_group_t);20void dispatch_group_wait(dispatch_group_t, int);21 22 23void dispatch_semaphore_wait(dispatch_semaphore_t, int);24void dispatch_semaphore_signal(dispatch_semaphore_t);25 26void func(void (^)(void));27void func_w_typedef(block_t);28 29int coin(void);30 31void use_semaphor_antipattern(void) {32  dispatch_semaphore_t sema = dispatch_semaphore_create(0);33 34  func(^{35      dispatch_semaphore_signal(sema);36  });37  dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}38}39 40// It's OK to use pattern in tests.41// We simply match the containing function name against ^test.42void test_no_warning(void) {43  dispatch_semaphore_t sema = dispatch_semaphore_create(0);44 45  func(^{46      dispatch_semaphore_signal(sema);47  });48  dispatch_semaphore_wait(sema, 100);49}50 51void use_semaphor_antipattern_multiple_times(void) {52  dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);53 54  func(^{55      dispatch_semaphore_signal(sema1);56  });57  dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}58 59  dispatch_semaphore_t sema2 = dispatch_semaphore_create(0);60 61  func(^{62      dispatch_semaphore_signal(sema2);63  });64  dispatch_semaphore_wait(sema2, 100); // expected-warning{{Waiting on a callback using a semaphore}}65}66 67void use_semaphor_antipattern_multiple_wait(void) {68  dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);69 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}}76}77 78void warn_incorrect_order(void) {79  // FIXME: ASTMatchers do not allow ordered matching, so would match even80  // if out of order.81  dispatch_semaphore_t sema = dispatch_semaphore_create(0);82 83  dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}84  func(^{85      dispatch_semaphore_signal(sema);86  });87}88 89void warn_w_typedef(void) {90  dispatch_semaphore_t sema = dispatch_semaphore_create(0);91 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}}96}97 98void warn_nested_ast(void) {99  dispatch_semaphore_t sema = dispatch_semaphore_create(0);100 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}}111}112 113void use_semaphore_assignment(void) {114  dispatch_semaphore_t sema;115  sema = dispatch_semaphore_create(0);116 117  func(^{118      dispatch_semaphore_signal(sema);119  });120  dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}121}122 123void use_semaphore_assignment_init(void) {124  dispatch_semaphore_t sema = dispatch_semaphore_create(0);125  sema = dispatch_semaphore_create(1);126 127  func(^{128      dispatch_semaphore_signal(sema);129  });130  dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}131}132 133void differentsemaphoreok(void) {134  dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);135  dispatch_semaphore_t sema2 = dispatch_semaphore_create(0);136 137  func(^{138      dispatch_semaphore_signal(sema1);139  });140  dispatch_semaphore_wait(sema2, 100); // no-warning141}142 143void nosignalok(void) {144  dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);145  dispatch_semaphore_wait(sema1, 100);146}147 148void nowaitok(void) {149  dispatch_semaphore_t sema = dispatch_semaphore_create(0);150  func(^{151      dispatch_semaphore_signal(sema);152  });153}154 155void noblockok(void) {156  dispatch_semaphore_t sema = dispatch_semaphore_create(0);157  dispatch_semaphore_signal(sema);158  dispatch_semaphore_wait(sema, 100);159}160 161void 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);167}168 169void passed_semaphore_ok(dispatch_semaphore_t sema) {170  func(^{171      dispatch_semaphore_signal(sema);172  });173  dispatch_semaphore_wait(sema, 100);174}175 176void warn_with_cast(void) {177  dispatch_semaphore_t sema = dispatch_semaphore_create(0);178 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}}183}184 185@interface MyInterface1 : NSObject186-(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@end194 195@implementation MyInterface1196 197-(void)use_method_warn {198  dispatch_semaphore_t sema = dispatch_semaphore_create(0);199 200  func(^{201      dispatch_semaphore_signal(sema);202  });203  dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}204}205 206-(void) pass_block_as_second_param_warn {207  dispatch_semaphore_t sema = dispatch_semaphore_create(0);208 209  [self flag:1 acceptBlock:^{210      dispatch_semaphore_signal(sema);211  }];212  dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}213}214 215-(void)testNoWarn {216  dispatch_semaphore_t sema = dispatch_semaphore_create(0);217 218  func(^{219      dispatch_semaphore_signal(sema);220  });221  dispatch_semaphore_wait(sema, 100);222}223 224-(void)acceptBlock:(block_t) callback {225  callback();226}227 228-(void)flag:(int)flag acceptBlock:(block_t)callback {229  callback();230}231 232-(void)use_objc_callback_warn {233  dispatch_semaphore_t sema = dispatch_semaphore_create(0);234 235  [self acceptBlock:^{236      dispatch_semaphore_signal(sema);237  }];238  dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}239}240 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}}248 249}250 251void use_objc_and_c_callback(MyInterface1 *t) {252  dispatch_semaphore_t sema = dispatch_semaphore_create(0);253 254  func(^{255      dispatch_semaphore_signal(sema);256  });257  dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}258 259  dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);260 261  [t acceptBlock:^{262      dispatch_semaphore_signal(sema1);263  }];264  dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback}}265}266@end267 268// No warnings: class name contains "test"269@interface Test1 : NSObject270-(void)use_method_warn;271@end272 273@implementation Test1274-(void)use_method_warn {275  dispatch_semaphore_t sema = dispatch_semaphore_create(0);276 277  func(^{278      dispatch_semaphore_signal(sema);279  });280  dispatch_semaphore_wait(sema, 100);281}282@end283 284 285// No warnings: class name contains "mock"286@interface Mock1 : NSObject287-(void)use_method_warn;288@end289 290@implementation Mock1291-(void)use_method_warn {292  dispatch_semaphore_t sema = dispatch_semaphore_create(0);293 294  func(^{295      dispatch_semaphore_signal(sema);296  });297  dispatch_semaphore_wait(sema, 100);298}299@end300 301void dispatch_group_wait_func(MyInterface1 *M) {302  dispatch_group_t group = dispatch_group_create();303  dispatch_group_enter(group);304 305  func(^{306      dispatch_group_leave(group);307  });308  dispatch_group_wait(group, 100); // expected-warning{{Waiting on a callback using a group}}309}310 311 312void 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}}319}320 321void 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}}328 329  dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);330 331  [M acceptBlock:^{332      dispatch_semaphore_signal(sema1);333  }];334  dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}335}336 337void no_warn_on_nonzero_semaphore(MyInterface1 *M) {338  dispatch_semaphore_t sema1 = dispatch_semaphore_create(1);339 340  [M acceptBlock:^{341      dispatch_semaphore_signal(sema1);342  }];343  dispatch_semaphore_wait(sema1, 100); // no-warning344}345 346