|  | 
 | // 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 | 
 | } |