xref: /aosp_15_r20/external/clang/test/SemaCXX/warn-thread-safety-verbose.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wthread-safety-verbose -Wno-thread-safety-negative -fcxx-exceptions %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 
27*67e74705SXin Li class  __attribute__((lockable)) Mutex {
28*67e74705SXin Li  public:
29*67e74705SXin Li   void Lock() __attribute__((exclusive_lock_function));
30*67e74705SXin Li   void ReaderLock() __attribute__((shared_lock_function));
31*67e74705SXin Li   void Unlock() __attribute__((unlock_function));
32*67e74705SXin Li   bool TryLock() __attribute__((exclusive_trylock_function(true)));
33*67e74705SXin Li   bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
34*67e74705SXin Li   void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
35*67e74705SXin Li 
36*67e74705SXin Li   // for negative capabilities
operator !() const37*67e74705SXin Li   const Mutex& operator!() const { return *this; }
38*67e74705SXin Li 
39*67e74705SXin Li   void AssertHeld()       ASSERT_EXCLUSIVE_LOCK();
40*67e74705SXin Li   void AssertReaderHeld() ASSERT_SHARED_LOCK();
41*67e74705SXin Li };
42*67e74705SXin Li 
43*67e74705SXin Li 
44*67e74705SXin Li class Test {
45*67e74705SXin Li   Mutex mu;
46*67e74705SXin Li   int a GUARDED_BY(mu);  // expected-note3 {{Guarded_by declared here.}}
47*67e74705SXin Li 
48*67e74705SXin Li   void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu);
49*67e74705SXin Li   void foo2() SHARED_LOCKS_REQUIRED(mu);
50*67e74705SXin Li   void foo3() LOCKS_EXCLUDED(mu);
51*67e74705SXin Li 
test1()52*67e74705SXin Li   void test1() {  // expected-note {{Thread warning in function 'test1'}}
53*67e74705SXin Li     a = 0;        // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
54*67e74705SXin Li   }
55*67e74705SXin Li 
test2()56*67e74705SXin Li   void test2() {  // expected-note {{Thread warning in function 'test2'}}
57*67e74705SXin Li     int b = a;    // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
58*67e74705SXin Li   }
59*67e74705SXin Li 
test3()60*67e74705SXin Li   void test3() {  // expected-note {{Thread warning in function 'test3'}}
61*67e74705SXin Li     foo1();       // expected-warning {{calling function 'foo1' requires holding mutex 'mu' exclusively}}
62*67e74705SXin Li   }
63*67e74705SXin Li 
test4()64*67e74705SXin Li   void test4() {  // expected-note {{Thread warning in function 'test4'}}
65*67e74705SXin Li     foo2();       // expected-warning {{calling function 'foo2' requires holding mutex 'mu'}}
66*67e74705SXin Li   }
67*67e74705SXin Li 
test5()68*67e74705SXin Li   void test5() {  // expected-note {{Thread warning in function 'test5'}}
69*67e74705SXin Li     mu.ReaderLock();
70*67e74705SXin Li     foo1();       // expected-warning {{calling function 'foo1' requires holding mutex 'mu' exclusively}}
71*67e74705SXin Li     mu.Unlock();
72*67e74705SXin Li   }
73*67e74705SXin Li 
test6()74*67e74705SXin Li   void test6() {  // expected-note {{Thread warning in function 'test6'}}
75*67e74705SXin Li     mu.ReaderLock();
76*67e74705SXin Li     a = 0;        // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
77*67e74705SXin Li     mu.Unlock();
78*67e74705SXin Li   }
79*67e74705SXin Li 
test7()80*67e74705SXin Li   void test7() {  // expected-note {{Thread warning in function 'test7'}}
81*67e74705SXin Li     mu.Lock();
82*67e74705SXin Li     foo3();       // expected-warning {{cannot call function 'foo3' while mutex 'mu' is held}}
83*67e74705SXin Li     mu.Unlock();
84*67e74705SXin Li   }
85*67e74705SXin Li };
86*67e74705SXin Li 
87