mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 01:36:38 +00:00

without prototypes. This patch converts the function signatures to have a prototype for the situations where the test is not specific to K&R C declarations. e.g., void func(); becomes void func(void); This is the ninth batch of tests being updated (there are a significant number of other tests left to be updated).
346 lines
9.0 KiB
Objective-C
346 lines
9.0 KiB
Objective-C
// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.performance.GCDAntipattern %s -fblocks -verify
|
|
typedef signed char BOOL;
|
|
@protocol NSObject - (BOOL)isEqual:(id)object; @end
|
|
@interface NSObject <NSObject> {}
|
|
+(id)alloc;
|
|
-(id)init;
|
|
-(id)autorelease;
|
|
-(id)copy;
|
|
-(id)retain;
|
|
@end
|
|
|
|
typedef int dispatch_semaphore_t;
|
|
typedef int dispatch_group_t;
|
|
typedef void (^block_t)(void);
|
|
|
|
dispatch_semaphore_t dispatch_semaphore_create(int);
|
|
dispatch_group_t dispatch_group_create(void);
|
|
void dispatch_group_enter(dispatch_group_t);
|
|
void dispatch_group_leave(dispatch_group_t);
|
|
void dispatch_group_wait(dispatch_group_t, int);
|
|
|
|
|
|
void dispatch_semaphore_wait(dispatch_semaphore_t, int);
|
|
void dispatch_semaphore_signal(dispatch_semaphore_t);
|
|
|
|
void func(void (^)(void));
|
|
void func_w_typedef(block_t);
|
|
|
|
int coin(void);
|
|
|
|
void use_semaphor_antipattern(void) {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
}
|
|
|
|
// It's OK to use pattern in tests.
|
|
// We simply match the containing function name against ^test.
|
|
void test_no_warning(void) {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100);
|
|
}
|
|
|
|
void use_semaphor_antipattern_multiple_times(void) {
|
|
dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema1);
|
|
});
|
|
dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
|
|
dispatch_semaphore_t sema2 = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema2);
|
|
});
|
|
dispatch_semaphore_wait(sema2, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
}
|
|
|
|
void use_semaphor_antipattern_multiple_wait(void) {
|
|
dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema1);
|
|
});
|
|
// FIXME: multiple waits on same semaphor should not raise a warning.
|
|
dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
}
|
|
|
|
void warn_incorrect_order(void) {
|
|
// FIXME: ASTMatchers do not allow ordered matching, so would match even
|
|
// if out of order.
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
}
|
|
|
|
void warn_w_typedef(void) {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
func_w_typedef(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
}
|
|
|
|
void warn_nested_ast(void) {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
if (coin()) {
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
} else {
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
}
|
|
dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
}
|
|
|
|
void use_semaphore_assignment(void) {
|
|
dispatch_semaphore_t sema;
|
|
sema = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
}
|
|
|
|
void use_semaphore_assignment_init(void) {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
sema = dispatch_semaphore_create(1);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
}
|
|
|
|
void differentsemaphoreok(void) {
|
|
dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
|
|
dispatch_semaphore_t sema2 = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema1);
|
|
});
|
|
dispatch_semaphore_wait(sema2, 100); // no-warning
|
|
}
|
|
|
|
void nosignalok(void) {
|
|
dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
|
|
dispatch_semaphore_wait(sema1, 100);
|
|
}
|
|
|
|
void nowaitok(void) {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
}
|
|
|
|
void noblockok(void) {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
dispatch_semaphore_signal(sema);
|
|
dispatch_semaphore_wait(sema, 100);
|
|
}
|
|
|
|
void storedblockok(void) {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
block_t b = ^{
|
|
dispatch_semaphore_signal(sema);
|
|
};
|
|
dispatch_semaphore_wait(sema, 100);
|
|
}
|
|
|
|
void passed_semaphore_ok(dispatch_semaphore_t sema) {
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100);
|
|
}
|
|
|
|
void warn_with_cast(void) {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal((int)sema);
|
|
});
|
|
dispatch_semaphore_wait((int)sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
}
|
|
|
|
@interface MyInterface1 : NSObject
|
|
-(void)use_method_warn;
|
|
-(void) pass_block_as_second_param_warn;
|
|
-(void)use_objc_callback_warn;
|
|
-(void) use_dispatch_group;
|
|
-(void)testNoWarn;
|
|
-(void)acceptBlock:(block_t)callback;
|
|
-(void)flag:(int)flag acceptBlock:(block_t)callback;
|
|
@end
|
|
|
|
@implementation MyInterface1
|
|
|
|
-(void)use_method_warn {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}
|
|
}
|
|
|
|
-(void) pass_block_as_second_param_warn {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
[self flag:1 acceptBlock:^{
|
|
dispatch_semaphore_signal(sema);
|
|
}];
|
|
dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}
|
|
}
|
|
|
|
-(void)testNoWarn {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100);
|
|
}
|
|
|
|
-(void)acceptBlock:(block_t) callback {
|
|
callback();
|
|
}
|
|
|
|
-(void)flag:(int)flag acceptBlock:(block_t)callback {
|
|
callback();
|
|
}
|
|
|
|
-(void)use_objc_callback_warn {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
[self acceptBlock:^{
|
|
dispatch_semaphore_signal(sema);
|
|
}];
|
|
dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback}}
|
|
}
|
|
|
|
-(void)use_dispatch_group {
|
|
dispatch_group_t group = dispatch_group_create();
|
|
dispatch_group_enter(group);
|
|
[self acceptBlock:^{
|
|
dispatch_group_leave(group);
|
|
}];
|
|
dispatch_group_wait(group, 100); // expected-warning{{Waiting on a callback using a group}}
|
|
|
|
}
|
|
|
|
void use_objc_and_c_callback(MyInterface1 *t) {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
|
|
dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
|
|
|
|
[t acceptBlock:^{
|
|
dispatch_semaphore_signal(sema1);
|
|
}];
|
|
dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback}}
|
|
}
|
|
@end
|
|
|
|
// No warnings: class name contains "test"
|
|
@interface Test1 : NSObject
|
|
-(void)use_method_warn;
|
|
@end
|
|
|
|
@implementation Test1
|
|
-(void)use_method_warn {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100);
|
|
}
|
|
@end
|
|
|
|
|
|
// No warnings: class name contains "mock"
|
|
@interface Mock1 : NSObject
|
|
-(void)use_method_warn;
|
|
@end
|
|
|
|
@implementation Mock1
|
|
-(void)use_method_warn {
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
|
|
func(^{
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, 100);
|
|
}
|
|
@end
|
|
|
|
void dispatch_group_wait_func(MyInterface1 *M) {
|
|
dispatch_group_t group = dispatch_group_create();
|
|
dispatch_group_enter(group);
|
|
|
|
func(^{
|
|
dispatch_group_leave(group);
|
|
});
|
|
dispatch_group_wait(group, 100); // expected-warning{{Waiting on a callback using a group}}
|
|
}
|
|
|
|
|
|
void dispatch_group_wait_cfunc(MyInterface1 *M) {
|
|
dispatch_group_t group = dispatch_group_create();
|
|
dispatch_group_enter(group);
|
|
[M acceptBlock:^{
|
|
dispatch_group_leave(group);
|
|
}];
|
|
dispatch_group_wait(group, 100); // expected-warning{{Waiting on a callback using a group}}
|
|
}
|
|
|
|
void dispatch_group_and_semaphore_use(MyInterface1 *M) {
|
|
dispatch_group_t group = dispatch_group_create();
|
|
dispatch_group_enter(group);
|
|
[M acceptBlock:^{
|
|
dispatch_group_leave(group);
|
|
}];
|
|
dispatch_group_wait(group, 100); // expected-warning{{Waiting on a callback using a group}}
|
|
|
|
dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
|
|
|
|
[M acceptBlock:^{
|
|
dispatch_semaphore_signal(sema1);
|
|
}];
|
|
dispatch_semaphore_wait(sema1, 100); // expected-warning{{Waiting on a callback using a semaphore}}
|
|
}
|
|
|
|
void no_warn_on_nonzero_semaphore(MyInterface1 *M) {
|
|
dispatch_semaphore_t sema1 = dispatch_semaphore_create(1);
|
|
|
|
[M acceptBlock:^{
|
|
dispatch_semaphore_signal(sema1);
|
|
}];
|
|
dispatch_semaphore_wait(sema1, 100); // no-warning
|
|
}
|
|
|