| // RUN: %clang_analyze_cc1 \ | |
| // RUN: -analyzer-checker=unix.BlockInCriticalSection \ | |
| // RUN: -std=c++11 \ | |
| // RUN: -analyzer-output text \ | |
| // RUN: -verify %s | |
| unsigned int sleep(unsigned int seconds) {return 0;} | |
| namespace std { | |
| namespace __detail { | |
| class __mutex_base { | |
| public: | |
| void lock(); | |
| }; | |
| } // namespace __detail | |
| class mutex : public __detail::__mutex_base{ | |
| public: | |
| void unlock(); | |
| bool try_lock(); | |
| }; | |
| } // namespace std | |
| void gh_99628() { | |
| std::mutex m; | |
| m.lock(); | |
| // expected-note@-1 {{Entering critical section here}} | |
| sleep(10); | |
| // expected-warning@-1 {{Call to blocking function 'sleep' inside of critical section}} | |
| // expected-note@-2 {{Call to blocking function 'sleep' inside of critical section}} | |
| m.unlock(); | |
| } | |
| void no_false_positive_gh_104241() { | |
| std::mutex m; | |
| m.lock(); | |
| // If inheritance not handled properly, this unlock might not match the lock | |
| // above because technically they act on different memory regions: | |
| // __mutex_base and mutex. | |
| m.unlock(); | |
| sleep(10); // no-warning | |
| } |