1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta %s 2*67e74705SXin Li 3*67e74705SXin Li #define LOCKABLE __attribute__ ((lockable)) 4*67e74705SXin Li #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable)) 5*67e74705SXin Li #define GUARDED_BY(x) __attribute__ ((guarded_by(x))) 6*67e74705SXin Li #define GUARDED_VAR __attribute__ ((guarded_var)) 7*67e74705SXin Li #define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x))) 8*67e74705SXin Li #define PT_GUARDED_VAR __attribute__ ((pt_guarded_var)) 9*67e74705SXin Li #define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__))) 10*67e74705SXin Li #define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__))) 11*67e74705SXin Li #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__))) 12*67e74705SXin Li #define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__))) 13*67e74705SXin Li #define ASSERT_EXCLUSIVE_LOCK(...) __attribute__ ((assert_exclusive_lock(__VA_ARGS__))) 14*67e74705SXin Li #define ASSERT_SHARED_LOCK(...) __attribute__ ((assert_shared_lock(__VA_ARGS__))) 15*67e74705SXin Li #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__))) 16*67e74705SXin Li #define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__))) 17*67e74705SXin Li #define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__))) 18*67e74705SXin Li #define LOCK_RETURNED(x) __attribute__ ((lock_returned(x))) 19*67e74705SXin Li #define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__))) 20*67e74705SXin Li #define EXCLUSIVE_LOCKS_REQUIRED(...) \ 21*67e74705SXin Li __attribute__ ((exclusive_locks_required(__VA_ARGS__))) 22*67e74705SXin Li #define SHARED_LOCKS_REQUIRED(...) \ 23*67e74705SXin Li __attribute__ ((shared_locks_required(__VA_ARGS__))) 24*67e74705SXin Li #define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis)) 25*67e74705SXin Li 26*67e74705SXin Li // Define the mutex struct. 27*67e74705SXin Li // Simplified only for test purpose. 28*67e74705SXin Li struct LOCKABLE Mutex {}; 29*67e74705SXin Li 30*67e74705SXin Li struct Foo { 31*67e74705SXin Li struct Mutex *mu_; 32*67e74705SXin Li }; 33*67e74705SXin Li 34*67e74705SXin Li // Declare mutex lock/unlock functions. 35*67e74705SXin Li void mutex_exclusive_lock(struct Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu); 36*67e74705SXin Li void mutex_shared_lock(struct Mutex *mu) SHARED_LOCK_FUNCTION(mu); 37*67e74705SXin Li void mutex_unlock(struct Mutex *mu) UNLOCK_FUNCTION(mu); 38*67e74705SXin Li void mutex_shared_unlock(struct Mutex *mu) __attribute__((release_shared_capability(mu))); 39*67e74705SXin Li void mutex_exclusive_unlock(struct Mutex *mu) __attribute__((release_capability(mu))); 40*67e74705SXin Li 41*67e74705SXin Li // Define global variables. 42*67e74705SXin Li struct Mutex mu1; 43*67e74705SXin Li struct Mutex mu2 ACQUIRED_AFTER(mu1); 44*67e74705SXin Li struct Foo foo_ = {&mu1}; 45*67e74705SXin Li int a_ GUARDED_BY(foo_.mu_); 46*67e74705SXin Li int *b_ PT_GUARDED_BY(foo_.mu_) = &a_; 47*67e74705SXin Li int c_ GUARDED_VAR; 48*67e74705SXin Li int *d_ PT_GUARDED_VAR = &c_; 49*67e74705SXin Li 50*67e74705SXin Li // Define test functions. Foo_fun1(int i)51*67e74705SXin Liint Foo_fun1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) { 52*67e74705SXin Li return i; 53*67e74705SXin Li } 54*67e74705SXin Li Foo_fun2(int i)55*67e74705SXin Liint Foo_fun2(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1) { 56*67e74705SXin Li return i; 57*67e74705SXin Li } 58*67e74705SXin Li Foo_func3(int i)59*67e74705SXin Liint Foo_func3(int i) LOCKS_EXCLUDED(mu1, mu2) { 60*67e74705SXin Li return i; 61*67e74705SXin Li } 62*67e74705SXin Li Bar_fun1(int i)63*67e74705SXin Listatic int Bar_fun1(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1) { 64*67e74705SXin Li return i; 65*67e74705SXin Li } 66*67e74705SXin Li set_value(int * a,int value)67*67e74705SXin Livoid set_value(int *a, int value) EXCLUSIVE_LOCKS_REQUIRED(foo_.mu_) { 68*67e74705SXin Li *a = value; 69*67e74705SXin Li } 70*67e74705SXin Li get_value(int * p)71*67e74705SXin Liint get_value(int *p) SHARED_LOCKS_REQUIRED(foo_.mu_){ 72*67e74705SXin Li return *p; 73*67e74705SXin Li } 74*67e74705SXin Li main()75*67e74705SXin Liint main() { 76*67e74705SXin Li 77*67e74705SXin Li Foo_fun1(1); // expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu2'}} \ 78*67e74705SXin Li expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu1' exclusively}} 79*67e74705SXin Li 80*67e74705SXin Li mutex_exclusive_lock(&mu1); 81*67e74705SXin Li mutex_shared_lock(&mu2); 82*67e74705SXin Li Foo_fun1(1); 83*67e74705SXin Li 84*67e74705SXin Li mutex_shared_lock(&mu1); // expected-warning{{acquiring mutex 'mu1' that is already held}} \ 85*67e74705SXin Li expected-warning{{mutex 'mu1' must be acquired before 'mu2'}} 86*67e74705SXin Li mutex_unlock(&mu1); 87*67e74705SXin Li mutex_unlock(&mu2); 88*67e74705SXin Li mutex_shared_lock(&mu1); 89*67e74705SXin Li mutex_exclusive_lock(&mu2); 90*67e74705SXin Li Foo_fun2(2); 91*67e74705SXin Li 92*67e74705SXin Li mutex_unlock(&mu2); 93*67e74705SXin Li mutex_unlock(&mu1); 94*67e74705SXin Li mutex_exclusive_lock(&mu1); 95*67e74705SXin Li Bar_fun1(3); 96*67e74705SXin Li mutex_unlock(&mu1); 97*67e74705SXin Li 98*67e74705SXin Li mutex_exclusive_lock(&mu1); 99*67e74705SXin Li Foo_func3(4); // expected-warning{{cannot call function 'Foo_func3' while mutex 'mu1' is held}} 100*67e74705SXin Li mutex_unlock(&mu1); 101*67e74705SXin Li 102*67e74705SXin Li Foo_func3(5); 103*67e74705SXin Li 104*67e74705SXin Li set_value(&a_, 0); // expected-warning{{calling function 'set_value' requires holding mutex 'foo_.mu_' exclusively}} 105*67e74705SXin Li get_value(b_); // expected-warning{{calling function 'get_value' requires holding mutex 'foo_.mu_'}} 106*67e74705SXin Li mutex_exclusive_lock(foo_.mu_); 107*67e74705SXin Li set_value(&a_, 1); 108*67e74705SXin Li mutex_unlock(foo_.mu_); 109*67e74705SXin Li mutex_shared_lock(foo_.mu_); 110*67e74705SXin Li (void)(get_value(b_) == 1); 111*67e74705SXin Li mutex_unlock(foo_.mu_); 112*67e74705SXin Li 113*67e74705SXin Li c_ = 0; // expected-warning{{writing variable 'c_' requires holding any mutex exclusively}} 114*67e74705SXin Li (void)(*d_ == 0); // expected-warning{{reading the value pointed to by 'd_' requires holding any mutex}} 115*67e74705SXin Li mutex_exclusive_lock(foo_.mu_); 116*67e74705SXin Li c_ = 1; 117*67e74705SXin Li (void)(*d_ == 1); 118*67e74705SXin Li mutex_unlock(foo_.mu_); 119*67e74705SXin Li 120*67e74705SXin Li mutex_exclusive_lock(&mu1); 121*67e74705SXin Li mutex_shared_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' using shared access, expected exclusive access}} 122*67e74705SXin Li mutex_exclusive_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' that was not held}} 123*67e74705SXin Li 124*67e74705SXin Li mutex_shared_lock(&mu1); 125*67e74705SXin Li mutex_exclusive_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' using exclusive access, expected shared access}} 126*67e74705SXin Li mutex_shared_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' that was not held}} 127*67e74705SXin Li 128*67e74705SXin Li return 0; 129*67e74705SXin Li } 130