xref: /aosp_15_r20/external/clang/test/Sema/warn-thread-safety-analysis.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
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 Li int 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 Li int 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 Li int 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 Li static 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 Li void 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 Li int get_value(int *p) SHARED_LOCKS_REQUIRED(foo_.mu_){
72*67e74705SXin Li   return *p;
73*67e74705SXin Li }
74*67e74705SXin Li 
main()75*67e74705SXin Li int 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