diff options
| author | George Karpenkov <ekarpenkov@apple.com> | 2018-03-05 22:03:32 +0000 |
|---|---|---|
| committer | George Karpenkov <ekarpenkov@apple.com> | 2018-03-05 22:03:32 +0000 |
| commit | 436d5cc7ee39f6b395c6581eb30c010b050705bc (patch) | |
| tree | 9518f3d20aa032ea12c6d60722e483b3bbf5d51f /clang/test/gcdasyncsemaphorechecker_test.m | |
| parent | bf320ee335888af71d0f82f0f57f21b4b3531f6d (diff) | |
| download | bcm5719-llvm-436d5cc7ee39f6b395c6581eb30c010b050705bc.tar.gz bcm5719-llvm-436d5cc7ee39f6b395c6581eb30c010b050705bc.zip | |
[analyzer] AST-matching checker to detect global central dispatch performance anti-pattern
rdar://37312818
NB: The checker does not care about the ordering of callbacks, see the
relevant FIXME in tests.
Differential Revision: https://reviews.llvm.org/D44059
llvm-svn: 326746
Diffstat (limited to 'clang/test/gcdasyncsemaphorechecker_test.m')
| -rw-r--r-- | clang/test/gcdasyncsemaphorechecker_test.m | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/clang/test/gcdasyncsemaphorechecker_test.m b/clang/test/gcdasyncsemaphorechecker_test.m new file mode 100644 index 00000000000..e65ae3d7feb --- /dev/null +++ b/clang/test/gcdasyncsemaphorechecker_test.m @@ -0,0 +1,169 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.osx.GCDAsyncSemaphore %s -fblocks -verify +// +typedef int dispatch_semaphore_t; +typedef void (^block_t)(); + +dispatch_semaphore_t dispatch_semaphore_create(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 use_semaphor_antipattern() { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + func(^{ + dispatch_semaphore_signal(sema); + }); + dispatch_semaphore_wait(sema, 100); // expected-warning{{Possible semaphore performance anti-pattern}} +} + +// It's OK to use pattern in tests. +// We simply match the containing function name against ^test. +void test_no_warning() { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + func(^{ + dispatch_semaphore_signal(sema); + }); + dispatch_semaphore_wait(sema, 100); +} + +void use_semaphor_antipattern_multiple_times() { + dispatch_semaphore_t sema1 = dispatch_semaphore_create(0); + + func(^{ + dispatch_semaphore_signal(sema1); + }); + dispatch_semaphore_wait(sema1, 100); // expected-warning{{Possible semaphore performance anti-pattern}} + + dispatch_semaphore_t sema2 = dispatch_semaphore_create(0); + + func(^{ + dispatch_semaphore_signal(sema2); + }); + dispatch_semaphore_wait(sema2, 100); // expected-warning{{Possible semaphore performance anti-pattern}} +} + +void use_semaphor_antipattern_multiple_wait() { + 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{{Possible semaphore performance anti-pattern}} + dispatch_semaphore_wait(sema1, 100); // expected-warning{{Possible semaphore performance anti-pattern}} +} + +void warn_incorrect_order() { + // 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{{Possible semaphore performance anti-pattern}} + func(^{ + dispatch_semaphore_signal(sema); + }); +} + +void warn_w_typedef() { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + func_w_typedef(^{ + dispatch_semaphore_signal(sema); + }); + dispatch_semaphore_wait(sema, 100); // expected-warning{{Possible semaphore performance anti-pattern}} +} + +void warn_nested_ast() { + 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{{Possible semaphore performance anti-pattern}} +} + +void use_semaphore_assignment() { + dispatch_semaphore_t sema; + sema = dispatch_semaphore_create(0); + + func(^{ + dispatch_semaphore_signal(sema); + }); + dispatch_semaphore_wait(sema, 100); // expected-warning{{Possible semaphore performance anti-pattern}} +} + +void use_semaphore_assignment_init() { + 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{{Possible semaphore performance anti-pattern}} +} + +void differentsemaphoreok() { + 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() { + dispatch_semaphore_t sema1 = dispatch_semaphore_create(0); + dispatch_semaphore_wait(sema1, 100); +} + +void nowaitok() { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + func(^{ + dispatch_semaphore_signal(sema); + }); +} + +void noblockok() { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + dispatch_semaphore_signal(sema); + dispatch_semaphore_wait(sema, 100); +} + +void storedblockok() { + 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() { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + func(^{ + dispatch_semaphore_signal((int)sema); + }); + dispatch_semaphore_wait((int)sema, 100); // expected-warning{{Possible semaphore performance anti-pattern}} +} + + |

