xref: /minix3/external/bsd/llvm/dist/clang/test/SemaCXX/warn-thread-safety-parsing.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
2*f4a2713aSLionel Sambuc 
3*f4a2713aSLionel Sambuc #define LOCKABLE            __attribute__ ((lockable))
4*f4a2713aSLionel Sambuc #define SCOPED_LOCKABLE     __attribute__ ((scoped_lockable))
5*f4a2713aSLionel Sambuc #define GUARDED_BY(x)       __attribute__ ((guarded_by(x)))
6*f4a2713aSLionel Sambuc #define GUARDED_VAR         __attribute__ ((guarded_var))
7*f4a2713aSLionel Sambuc #define PT_GUARDED_BY(x)    __attribute__ ((pt_guarded_by(x)))
8*f4a2713aSLionel Sambuc #define PT_GUARDED_VAR      __attribute__ ((pt_guarded_var))
9*f4a2713aSLionel Sambuc #define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
10*f4a2713aSLionel Sambuc #define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
11*f4a2713aSLionel Sambuc #define EXCLUSIVE_LOCK_FUNCTION(...)    __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
12*f4a2713aSLionel Sambuc #define SHARED_LOCK_FUNCTION(...)       __attribute__ ((shared_lock_function(__VA_ARGS__)))
13*f4a2713aSLionel Sambuc #define ASSERT_EXCLUSIVE_LOCK(...)      __attribute__ ((assert_exclusive_lock(__VA_ARGS__)))
14*f4a2713aSLionel Sambuc #define ASSERT_SHARED_LOCK(...)         __attribute__ ((assert_shared_lock(__VA_ARGS__)))
15*f4a2713aSLionel Sambuc #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
16*f4a2713aSLionel Sambuc #define SHARED_TRYLOCK_FUNCTION(...)    __attribute__ ((shared_trylock_function(__VA_ARGS__)))
17*f4a2713aSLionel Sambuc #define UNLOCK_FUNCTION(...)            __attribute__ ((unlock_function(__VA_ARGS__)))
18*f4a2713aSLionel Sambuc #define LOCK_RETURNED(x)    __attribute__ ((lock_returned(x)))
19*f4a2713aSLionel Sambuc #define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
20*f4a2713aSLionel Sambuc #define EXCLUSIVE_LOCKS_REQUIRED(...) \
21*f4a2713aSLionel Sambuc   __attribute__ ((exclusive_locks_required(__VA_ARGS__)))
22*f4a2713aSLionel Sambuc #define SHARED_LOCKS_REQUIRED(...) \
23*f4a2713aSLionel Sambuc   __attribute__ ((shared_locks_required(__VA_ARGS__)))
24*f4a2713aSLionel Sambuc #define NO_THREAD_SAFETY_ANALYSIS  __attribute__ ((no_thread_safety_analysis))
25*f4a2713aSLionel Sambuc 
26*f4a2713aSLionel Sambuc 
27*f4a2713aSLionel Sambuc class LOCKABLE Mutex {
28*f4a2713aSLionel Sambuc   public:
29*f4a2713aSLionel Sambuc   void Lock()          EXCLUSIVE_LOCK_FUNCTION();
30*f4a2713aSLionel Sambuc   void ReaderLock()    SHARED_LOCK_FUNCTION();
31*f4a2713aSLionel Sambuc   void Unlock()        UNLOCK_FUNCTION();
32*f4a2713aSLionel Sambuc 
33*f4a2713aSLionel Sambuc   bool TryLock()       EXCLUSIVE_TRYLOCK_FUNCTION(true);
34*f4a2713aSLionel Sambuc   bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true);
35*f4a2713aSLionel Sambuc 
36*f4a2713aSLionel Sambuc   void AssertHeld()       ASSERT_EXCLUSIVE_LOCK();
37*f4a2713aSLionel Sambuc   void AssertReaderHeld() ASSERT_SHARED_LOCK();
38*f4a2713aSLionel Sambuc };
39*f4a2713aSLionel Sambuc 
40*f4a2713aSLionel Sambuc class UnlockableMu{
41*f4a2713aSLionel Sambuc };
42*f4a2713aSLionel Sambuc 
43*f4a2713aSLionel Sambuc class MuWrapper {
44*f4a2713aSLionel Sambuc   public:
45*f4a2713aSLionel Sambuc   Mutex mu;
46*f4a2713aSLionel Sambuc   Mutex getMu() {
47*f4a2713aSLionel Sambuc     return mu;
48*f4a2713aSLionel Sambuc   }
49*f4a2713aSLionel Sambuc   Mutex * getMuPointer() {
50*f4a2713aSLionel Sambuc     return μ
51*f4a2713aSLionel Sambuc   }
52*f4a2713aSLionel Sambuc };
53*f4a2713aSLionel Sambuc 
54*f4a2713aSLionel Sambuc 
55*f4a2713aSLionel Sambuc class MuDoubleWrapper {
56*f4a2713aSLionel Sambuc   public:
57*f4a2713aSLionel Sambuc   MuWrapper* muWrapper;
58*f4a2713aSLionel Sambuc   MuWrapper* getWrapper() {
59*f4a2713aSLionel Sambuc     return muWrapper;
60*f4a2713aSLionel Sambuc   }
61*f4a2713aSLionel Sambuc };
62*f4a2713aSLionel Sambuc 
63*f4a2713aSLionel Sambuc Mutex mu1;
64*f4a2713aSLionel Sambuc UnlockableMu umu;
65*f4a2713aSLionel Sambuc Mutex mu2;
66*f4a2713aSLionel Sambuc MuWrapper muWrapper;
67*f4a2713aSLionel Sambuc MuDoubleWrapper muDoubleWrapper;
68*f4a2713aSLionel Sambuc Mutex* muPointer;
69*f4a2713aSLionel Sambuc Mutex** muDoublePointer = & muPointer;
70*f4a2713aSLionel Sambuc Mutex& muRef = mu1;
71*f4a2713aSLionel Sambuc 
72*f4a2713aSLionel Sambuc //---------------------------------------//
73*f4a2713aSLionel Sambuc // Scoping tests
74*f4a2713aSLionel Sambuc //--------------------------------------//
75*f4a2713aSLionel Sambuc 
76*f4a2713aSLionel Sambuc class Foo {
77*f4a2713aSLionel Sambuc   Mutex foomu;
78*f4a2713aSLionel Sambuc   void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu);
79*f4a2713aSLionel Sambuc };
80*f4a2713aSLionel Sambuc 
81*f4a2713aSLionel Sambuc class Foo2 {
82*f4a2713aSLionel Sambuc   void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu);
83*f4a2713aSLionel Sambuc   Mutex foomu;
84*f4a2713aSLionel Sambuc };
85*f4a2713aSLionel Sambuc 
86*f4a2713aSLionel Sambuc class Bar {
87*f4a2713aSLionel Sambuc  Mutex barmu;
88*f4a2713aSLionel Sambuc  Mutex barmu2 ACQUIRED_AFTER(barmu);
89*f4a2713aSLionel Sambuc };
90*f4a2713aSLionel Sambuc 
91*f4a2713aSLionel Sambuc 
92*f4a2713aSLionel Sambuc //-----------------------------------------//
93*f4a2713aSLionel Sambuc //   No Thread Safety Analysis (noanal)    //
94*f4a2713aSLionel Sambuc //-----------------------------------------//
95*f4a2713aSLionel Sambuc 
96*f4a2713aSLionel Sambuc // FIXME: Right now we cannot parse attributes put on function definitions
97*f4a2713aSLionel Sambuc // We would like to patch this at some point.
98*f4a2713aSLionel Sambuc 
99*f4a2713aSLionel Sambuc #if !__has_attribute(no_thread_safety_analysis)
100*f4a2713aSLionel Sambuc #error "Should support no_thread_safety_analysis attribute"
101*f4a2713aSLionel Sambuc #endif
102*f4a2713aSLionel Sambuc 
103*f4a2713aSLionel Sambuc void noanal_fun() NO_THREAD_SAFETY_ANALYSIS;
104*f4a2713aSLionel Sambuc 
105*f4a2713aSLionel Sambuc void noanal_fun_args() __attribute__((no_thread_safety_analysis(1))); // \
106*f4a2713aSLionel Sambuc   // expected-error {{'no_thread_safety_analysis' attribute takes no arguments}}
107*f4a2713aSLionel Sambuc 
108*f4a2713aSLionel Sambuc int noanal_testfn(int y) NO_THREAD_SAFETY_ANALYSIS;
109*f4a2713aSLionel Sambuc 
110*f4a2713aSLionel Sambuc int noanal_testfn(int y) {
111*f4a2713aSLionel Sambuc   int x NO_THREAD_SAFETY_ANALYSIS = y; // \
112*f4a2713aSLionel Sambuc     // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
113*f4a2713aSLionel Sambuc   return x;
114*f4a2713aSLionel Sambuc };
115*f4a2713aSLionel Sambuc 
116*f4a2713aSLionel Sambuc int noanal_test_var NO_THREAD_SAFETY_ANALYSIS; // \
117*f4a2713aSLionel Sambuc   // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
118*f4a2713aSLionel Sambuc 
119*f4a2713aSLionel Sambuc class NoanalFoo {
120*f4a2713aSLionel Sambuc  private:
121*f4a2713aSLionel Sambuc   int test_field NO_THREAD_SAFETY_ANALYSIS; // \
122*f4a2713aSLionel Sambuc     // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
123*f4a2713aSLionel Sambuc   void test_method() NO_THREAD_SAFETY_ANALYSIS;
124*f4a2713aSLionel Sambuc };
125*f4a2713aSLionel Sambuc 
126*f4a2713aSLionel Sambuc class NO_THREAD_SAFETY_ANALYSIS NoanalTestClass { // \
127*f4a2713aSLionel Sambuc   // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
128*f4a2713aSLionel Sambuc };
129*f4a2713aSLionel Sambuc 
130*f4a2713aSLionel Sambuc void noanal_fun_params(int lvar NO_THREAD_SAFETY_ANALYSIS); // \
131*f4a2713aSLionel Sambuc   // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
132*f4a2713aSLionel Sambuc 
133*f4a2713aSLionel Sambuc 
134*f4a2713aSLionel Sambuc //-----------------------------------------//
135*f4a2713aSLionel Sambuc //  Guarded Var Attribute (gv)
136*f4a2713aSLionel Sambuc //-----------------------------------------//
137*f4a2713aSLionel Sambuc 
138*f4a2713aSLionel Sambuc #if !__has_attribute(guarded_var)
139*f4a2713aSLionel Sambuc #error "Should support guarded_var attribute"
140*f4a2713aSLionel Sambuc #endif
141*f4a2713aSLionel Sambuc 
142*f4a2713aSLionel Sambuc int gv_var_noargs GUARDED_VAR;
143*f4a2713aSLionel Sambuc 
144*f4a2713aSLionel Sambuc int gv_var_args __attribute__((guarded_var(1))); // \
145*f4a2713aSLionel Sambuc   // expected-error {{'guarded_var' attribute takes no arguments}}
146*f4a2713aSLionel Sambuc 
147*f4a2713aSLionel Sambuc class GVFoo {
148*f4a2713aSLionel Sambuc  private:
149*f4a2713aSLionel Sambuc   int gv_field_noargs GUARDED_VAR;
150*f4a2713aSLionel Sambuc   int gv_field_args __attribute__((guarded_var(1))); // \
151*f4a2713aSLionel Sambuc     // expected-error {{'guarded_var' attribute takes no arguments}}
152*f4a2713aSLionel Sambuc };
153*f4a2713aSLionel Sambuc 
154*f4a2713aSLionel Sambuc class GUARDED_VAR GV { // \
155*f4a2713aSLionel Sambuc   // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
156*f4a2713aSLionel Sambuc };
157*f4a2713aSLionel Sambuc 
158*f4a2713aSLionel Sambuc void gv_function() GUARDED_VAR; // \
159*f4a2713aSLionel Sambuc   // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
160*f4a2713aSLionel Sambuc 
161*f4a2713aSLionel Sambuc void gv_function_params(int gv_lvar GUARDED_VAR); // \
162*f4a2713aSLionel Sambuc   // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
163*f4a2713aSLionel Sambuc 
164*f4a2713aSLionel Sambuc int gv_testfn(int y){
165*f4a2713aSLionel Sambuc   int x GUARDED_VAR = y; // \
166*f4a2713aSLionel Sambuc     // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
167*f4a2713aSLionel Sambuc   return x;
168*f4a2713aSLionel Sambuc }
169*f4a2713aSLionel Sambuc 
170*f4a2713aSLionel Sambuc //-----------------------------------------//
171*f4a2713aSLionel Sambuc //   Pt Guarded Var Attribute (pgv)
172*f4a2713aSLionel Sambuc //-----------------------------------------//
173*f4a2713aSLionel Sambuc 
174*f4a2713aSLionel Sambuc //FIXME: add support for boost::scoped_ptr<int> fancyptr  and references
175*f4a2713aSLionel Sambuc 
176*f4a2713aSLionel Sambuc #if !__has_attribute(pt_guarded_var)
177*f4a2713aSLionel Sambuc #error "Should support pt_guarded_var attribute"
178*f4a2713aSLionel Sambuc #endif
179*f4a2713aSLionel Sambuc 
180*f4a2713aSLionel Sambuc int *pgv_pt_var_noargs PT_GUARDED_VAR;
181*f4a2713aSLionel Sambuc 
182*f4a2713aSLionel Sambuc int pgv_var_noargs PT_GUARDED_VAR; // \
183*f4a2713aSLionel Sambuc     // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
184*f4a2713aSLionel Sambuc 
185*f4a2713aSLionel Sambuc class PGVFoo {
186*f4a2713aSLionel Sambuc  private:
187*f4a2713aSLionel Sambuc   int *pt_field_noargs PT_GUARDED_VAR;
188*f4a2713aSLionel Sambuc   int field_noargs PT_GUARDED_VAR; // \
189*f4a2713aSLionel Sambuc     // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
190*f4a2713aSLionel Sambuc   int *gv_field_args __attribute__((pt_guarded_var(1))); // \
191*f4a2713aSLionel Sambuc     // expected-error {{'pt_guarded_var' attribute takes no arguments}}
192*f4a2713aSLionel Sambuc };
193*f4a2713aSLionel Sambuc 
194*f4a2713aSLionel Sambuc class PT_GUARDED_VAR PGV { // \
195*f4a2713aSLionel Sambuc   // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
196*f4a2713aSLionel Sambuc };
197*f4a2713aSLionel Sambuc 
198*f4a2713aSLionel Sambuc int *pgv_var_args __attribute__((pt_guarded_var(1))); // \
199*f4a2713aSLionel Sambuc   // expected-error {{'pt_guarded_var' attribute takes no arguments}}
200*f4a2713aSLionel Sambuc 
201*f4a2713aSLionel Sambuc 
202*f4a2713aSLionel Sambuc void pgv_function() PT_GUARDED_VAR; // \
203*f4a2713aSLionel Sambuc   // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
204*f4a2713aSLionel Sambuc 
205*f4a2713aSLionel Sambuc void pgv_function_params(int *gv_lvar PT_GUARDED_VAR); // \
206*f4a2713aSLionel Sambuc   // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
207*f4a2713aSLionel Sambuc 
208*f4a2713aSLionel Sambuc void pgv_testfn(int y){
209*f4a2713aSLionel Sambuc   int *x PT_GUARDED_VAR = new int(0); // \
210*f4a2713aSLionel Sambuc     // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
211*f4a2713aSLionel Sambuc   delete x;
212*f4a2713aSLionel Sambuc }
213*f4a2713aSLionel Sambuc 
214*f4a2713aSLionel Sambuc //-----------------------------------------//
215*f4a2713aSLionel Sambuc //  Lockable Attribute (l)
216*f4a2713aSLionel Sambuc //-----------------------------------------//
217*f4a2713aSLionel Sambuc 
218*f4a2713aSLionel Sambuc //FIXME: In future we may want to add support for structs, ObjC classes, etc.
219*f4a2713aSLionel Sambuc 
220*f4a2713aSLionel Sambuc #if !__has_attribute(lockable)
221*f4a2713aSLionel Sambuc #error "Should support lockable attribute"
222*f4a2713aSLionel Sambuc #endif
223*f4a2713aSLionel Sambuc 
224*f4a2713aSLionel Sambuc class LOCKABLE LTestClass {
225*f4a2713aSLionel Sambuc };
226*f4a2713aSLionel Sambuc 
227*f4a2713aSLionel Sambuc class __attribute__((lockable (1))) LTestClass_args { // \
228*f4a2713aSLionel Sambuc     // expected-error {{'lockable' attribute takes no arguments}}
229*f4a2713aSLionel Sambuc };
230*f4a2713aSLionel Sambuc 
231*f4a2713aSLionel Sambuc void l_test_function() LOCKABLE;  // \
232*f4a2713aSLionel Sambuc   // expected-warning {{'lockable' attribute only applies to classes}}
233*f4a2713aSLionel Sambuc 
234*f4a2713aSLionel Sambuc int l_testfn(int y) {
235*f4a2713aSLionel Sambuc   int x LOCKABLE = y; // \
236*f4a2713aSLionel Sambuc     // expected-warning {{'lockable' attribute only applies to classes}}
237*f4a2713aSLionel Sambuc   return x;
238*f4a2713aSLionel Sambuc }
239*f4a2713aSLionel Sambuc 
240*f4a2713aSLionel Sambuc int l_test_var LOCKABLE; // \
241*f4a2713aSLionel Sambuc   // expected-warning {{'lockable' attribute only applies to classes}}
242*f4a2713aSLionel Sambuc 
243*f4a2713aSLionel Sambuc class LFoo {
244*f4a2713aSLionel Sambuc  private:
245*f4a2713aSLionel Sambuc   int test_field LOCKABLE; // \
246*f4a2713aSLionel Sambuc     // expected-warning {{'lockable' attribute only applies to classes}}
247*f4a2713aSLionel Sambuc   void test_method() LOCKABLE; // \
248*f4a2713aSLionel Sambuc     // expected-warning {{'lockable' attribute only applies to classes}}
249*f4a2713aSLionel Sambuc };
250*f4a2713aSLionel Sambuc 
251*f4a2713aSLionel Sambuc 
252*f4a2713aSLionel Sambuc void l_function_params(int lvar LOCKABLE); // \
253*f4a2713aSLionel Sambuc   // expected-warning {{'lockable' attribute only applies to classes}}
254*f4a2713aSLionel Sambuc 
255*f4a2713aSLionel Sambuc 
256*f4a2713aSLionel Sambuc //-----------------------------------------//
257*f4a2713aSLionel Sambuc //  Scoped Lockable Attribute (sl)
258*f4a2713aSLionel Sambuc //-----------------------------------------//
259*f4a2713aSLionel Sambuc 
260*f4a2713aSLionel Sambuc #if !__has_attribute(scoped_lockable)
261*f4a2713aSLionel Sambuc #error "Should support scoped_lockable attribute"
262*f4a2713aSLionel Sambuc #endif
263*f4a2713aSLionel Sambuc 
264*f4a2713aSLionel Sambuc class SCOPED_LOCKABLE SLTestClass {
265*f4a2713aSLionel Sambuc };
266*f4a2713aSLionel Sambuc 
267*f4a2713aSLionel Sambuc class __attribute__((scoped_lockable (1))) SLTestClass_args { // \
268*f4a2713aSLionel Sambuc   // expected-error {{'scoped_lockable' attribute takes no arguments}}
269*f4a2713aSLionel Sambuc };
270*f4a2713aSLionel Sambuc 
271*f4a2713aSLionel Sambuc void sl_test_function() SCOPED_LOCKABLE;  // \
272*f4a2713aSLionel Sambuc   // expected-warning {{'scoped_lockable' attribute only applies to classes}}
273*f4a2713aSLionel Sambuc 
274*f4a2713aSLionel Sambuc int sl_testfn(int y) {
275*f4a2713aSLionel Sambuc   int x SCOPED_LOCKABLE = y; // \
276*f4a2713aSLionel Sambuc     // expected-warning {{'scoped_lockable' attribute only applies to classes}}
277*f4a2713aSLionel Sambuc   return x;
278*f4a2713aSLionel Sambuc }
279*f4a2713aSLionel Sambuc 
280*f4a2713aSLionel Sambuc int sl_test_var SCOPED_LOCKABLE; // \
281*f4a2713aSLionel Sambuc   // expected-warning {{'scoped_lockable' attribute only applies to classes}}
282*f4a2713aSLionel Sambuc 
283*f4a2713aSLionel Sambuc class SLFoo {
284*f4a2713aSLionel Sambuc  private:
285*f4a2713aSLionel Sambuc   int test_field SCOPED_LOCKABLE; // \
286*f4a2713aSLionel Sambuc     // expected-warning {{'scoped_lockable' attribute only applies to classes}}
287*f4a2713aSLionel Sambuc   void test_method() SCOPED_LOCKABLE; // \
288*f4a2713aSLionel Sambuc     // expected-warning {{'scoped_lockable' attribute only applies to classes}}
289*f4a2713aSLionel Sambuc };
290*f4a2713aSLionel Sambuc 
291*f4a2713aSLionel Sambuc 
292*f4a2713aSLionel Sambuc void sl_function_params(int lvar SCOPED_LOCKABLE); // \
293*f4a2713aSLionel Sambuc   // expected-warning {{'scoped_lockable' attribute only applies to classes}}
294*f4a2713aSLionel Sambuc 
295*f4a2713aSLionel Sambuc 
296*f4a2713aSLionel Sambuc //-----------------------------------------//
297*f4a2713aSLionel Sambuc //  Guarded By Attribute (gb)
298*f4a2713aSLionel Sambuc //-----------------------------------------//
299*f4a2713aSLionel Sambuc 
300*f4a2713aSLionel Sambuc // FIXME: Eventually, would we like this attribute to take more than 1 arg?
301*f4a2713aSLionel Sambuc 
302*f4a2713aSLionel Sambuc #if !__has_attribute(guarded_by)
303*f4a2713aSLionel Sambuc #error "Should support guarded_by attribute"
304*f4a2713aSLionel Sambuc #endif
305*f4a2713aSLionel Sambuc 
306*f4a2713aSLionel Sambuc //1. Check applied to the right types & argument number
307*f4a2713aSLionel Sambuc 
308*f4a2713aSLionel Sambuc int gb_var_arg GUARDED_BY(mu1);
309*f4a2713aSLionel Sambuc 
310*f4a2713aSLionel Sambuc int gb_non_ascii GUARDED_BY(L"wide"); // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
311*f4a2713aSLionel Sambuc 
312*f4a2713aSLionel Sambuc int gb_var_args __attribute__((guarded_by(mu1, mu2))); // \
313*f4a2713aSLionel Sambuc   // expected-error {{'guarded_by' attribute takes one argument}}
314*f4a2713aSLionel Sambuc 
315*f4a2713aSLionel Sambuc int gb_var_noargs __attribute__((guarded_by)); // \
316*f4a2713aSLionel Sambuc   // expected-error {{'guarded_by' attribute takes one argument}}
317*f4a2713aSLionel Sambuc 
318*f4a2713aSLionel Sambuc class GBFoo {
319*f4a2713aSLionel Sambuc  private:
320*f4a2713aSLionel Sambuc   int gb_field_noargs __attribute__((guarded_by)); // \
321*f4a2713aSLionel Sambuc     // expected-error {{'guarded_by' attribute takes one argument}}
322*f4a2713aSLionel Sambuc   int gb_field_args GUARDED_BY(mu1);
323*f4a2713aSLionel Sambuc };
324*f4a2713aSLionel Sambuc 
325*f4a2713aSLionel Sambuc class GUARDED_BY(mu1) GB { // \
326*f4a2713aSLionel Sambuc   // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
327*f4a2713aSLionel Sambuc };
328*f4a2713aSLionel Sambuc 
329*f4a2713aSLionel Sambuc void gb_function() GUARDED_BY(mu1); // \
330*f4a2713aSLionel Sambuc   // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
331*f4a2713aSLionel Sambuc 
332*f4a2713aSLionel Sambuc void gb_function_params(int gv_lvar GUARDED_BY(mu1)); // \
333*f4a2713aSLionel Sambuc   // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
334*f4a2713aSLionel Sambuc 
335*f4a2713aSLionel Sambuc int gb_testfn(int y){
336*f4a2713aSLionel Sambuc   int x GUARDED_BY(mu1) = y; // \
337*f4a2713aSLionel Sambuc     // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
338*f4a2713aSLionel Sambuc   return x;
339*f4a2713aSLionel Sambuc }
340*f4a2713aSLionel Sambuc 
341*f4a2713aSLionel Sambuc //2. Check argument parsing.
342*f4a2713aSLionel Sambuc 
343*f4a2713aSLionel Sambuc // legal attribute arguments
344*f4a2713aSLionel Sambuc int gb_var_arg_1 GUARDED_BY(muWrapper.mu);
345*f4a2713aSLionel Sambuc int gb_var_arg_2 GUARDED_BY(muDoubleWrapper.muWrapper->mu);
346*f4a2713aSLionel Sambuc int gb_var_arg_3 GUARDED_BY(muWrapper.getMu());
347*f4a2713aSLionel Sambuc int gb_var_arg_4 GUARDED_BY(*muWrapper.getMuPointer());
348*f4a2713aSLionel Sambuc int gb_var_arg_5 GUARDED_BY(&mu1);
349*f4a2713aSLionel Sambuc int gb_var_arg_6 GUARDED_BY(muRef);
350*f4a2713aSLionel Sambuc int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());
351*f4a2713aSLionel Sambuc int gb_var_arg_8 GUARDED_BY(muPointer);
352*f4a2713aSLionel Sambuc 
353*f4a2713aSLionel Sambuc 
354*f4a2713aSLionel Sambuc // illegal attribute arguments
355*f4a2713aSLionel Sambuc int gb_var_arg_bad_1 GUARDED_BY(1); // \
356*f4a2713aSLionel Sambuc   // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'int'}}
357*f4a2713aSLionel Sambuc int gb_var_arg_bad_2 GUARDED_BY("mu"); // \
358*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
359*f4a2713aSLionel Sambuc int gb_var_arg_bad_3 GUARDED_BY(muDoublePointer); // \
360*f4a2713aSLionel Sambuc   // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'class Mutex **'}}
361*f4a2713aSLionel Sambuc int gb_var_arg_bad_4 GUARDED_BY(umu); // \
362*f4a2713aSLionel Sambuc   // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class UnlockableMu'}}
363*f4a2713aSLionel Sambuc 
364*f4a2713aSLionel Sambuc //3.
365*f4a2713aSLionel Sambuc // Thread Safety analysis tests
366*f4a2713aSLionel Sambuc 
367*f4a2713aSLionel Sambuc 
368*f4a2713aSLionel Sambuc //-----------------------------------------//
369*f4a2713aSLionel Sambuc //  Pt Guarded By Attribute (pgb)
370*f4a2713aSLionel Sambuc //-----------------------------------------//
371*f4a2713aSLionel Sambuc 
372*f4a2713aSLionel Sambuc #if !__has_attribute(pt_guarded_by)
373*f4a2713aSLionel Sambuc #error "Should support pt_guarded_by attribute"
374*f4a2713aSLionel Sambuc #endif
375*f4a2713aSLionel Sambuc 
376*f4a2713aSLionel Sambuc //1. Check applied to the right types & argument number
377*f4a2713aSLionel Sambuc 
378*f4a2713aSLionel Sambuc int *pgb_var_noargs __attribute__((pt_guarded_by)); // \
379*f4a2713aSLionel Sambuc   // expected-error {{'pt_guarded_by' attribute takes one argument}}
380*f4a2713aSLionel Sambuc 
381*f4a2713aSLionel Sambuc int *pgb_ptr_var_arg PT_GUARDED_BY(mu1);
382*f4a2713aSLionel Sambuc 
383*f4a2713aSLionel Sambuc int *pgb_ptr_var_args __attribute__((pt_guarded_by(mu1, mu2))); // \
384*f4a2713aSLionel Sambuc   // expected-error {{'pt_guarded_by' attribute takes one argument}}
385*f4a2713aSLionel Sambuc 
386*f4a2713aSLionel Sambuc int pgb_var_args PT_GUARDED_BY(mu1); // \
387*f4a2713aSLionel Sambuc   // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
388*f4a2713aSLionel Sambuc 
389*f4a2713aSLionel Sambuc class PGBFoo {
390*f4a2713aSLionel Sambuc  private:
391*f4a2713aSLionel Sambuc   int *pgb_field_noargs __attribute__((pt_guarded_by)); // \
392*f4a2713aSLionel Sambuc     // expected-error {{'pt_guarded_by' attribute takes one argument}}
393*f4a2713aSLionel Sambuc   int *pgb_field_args PT_GUARDED_BY(mu1);
394*f4a2713aSLionel Sambuc };
395*f4a2713aSLionel Sambuc 
396*f4a2713aSLionel Sambuc class PT_GUARDED_BY(mu1) PGB { // \
397*f4a2713aSLionel Sambuc   // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
398*f4a2713aSLionel Sambuc };
399*f4a2713aSLionel Sambuc 
400*f4a2713aSLionel Sambuc void pgb_function() PT_GUARDED_BY(mu1); // \
401*f4a2713aSLionel Sambuc   // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
402*f4a2713aSLionel Sambuc 
403*f4a2713aSLionel Sambuc void pgb_function_params(int gv_lvar PT_GUARDED_BY(mu1)); // \
404*f4a2713aSLionel Sambuc   // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
405*f4a2713aSLionel Sambuc 
406*f4a2713aSLionel Sambuc void pgb_testfn(int y){
407*f4a2713aSLionel Sambuc   int *x PT_GUARDED_BY(mu1) = new int(0); // \
408*f4a2713aSLionel Sambuc     // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
409*f4a2713aSLionel Sambuc   delete x;
410*f4a2713aSLionel Sambuc }
411*f4a2713aSLionel Sambuc 
412*f4a2713aSLionel Sambuc //2. Check argument parsing.
413*f4a2713aSLionel Sambuc 
414*f4a2713aSLionel Sambuc // legal attribute arguments
415*f4a2713aSLionel Sambuc int * pgb_var_arg_1 PT_GUARDED_BY(muWrapper.mu);
416*f4a2713aSLionel Sambuc int * pgb_var_arg_2 PT_GUARDED_BY(muDoubleWrapper.muWrapper->mu);
417*f4a2713aSLionel Sambuc int * pgb_var_arg_3 PT_GUARDED_BY(muWrapper.getMu());
418*f4a2713aSLionel Sambuc int * pgb_var_arg_4 PT_GUARDED_BY(*muWrapper.getMuPointer());
419*f4a2713aSLionel Sambuc int * pgb_var_arg_5 PT_GUARDED_BY(&mu1);
420*f4a2713aSLionel Sambuc int * pgb_var_arg_6 PT_GUARDED_BY(muRef);
421*f4a2713aSLionel Sambuc int * pgb_var_arg_7 PT_GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());
422*f4a2713aSLionel Sambuc int * pgb_var_arg_8 PT_GUARDED_BY(muPointer);
423*f4a2713aSLionel Sambuc 
424*f4a2713aSLionel Sambuc 
425*f4a2713aSLionel Sambuc // illegal attribute arguments
426*f4a2713aSLionel Sambuc int * pgb_var_arg_bad_1 PT_GUARDED_BY(1); // \
427*f4a2713aSLionel Sambuc   // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
428*f4a2713aSLionel Sambuc int * pgb_var_arg_bad_2 PT_GUARDED_BY("mu"); // \
429*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}}
430*f4a2713aSLionel Sambuc int * pgb_var_arg_bad_3 PT_GUARDED_BY(muDoublePointer); // \
431*f4a2713aSLionel Sambuc   // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
432*f4a2713aSLionel Sambuc int * pgb_var_arg_bad_4 PT_GUARDED_BY(umu); // \
433*f4a2713aSLionel Sambuc   // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute}}
434*f4a2713aSLionel Sambuc 
435*f4a2713aSLionel Sambuc 
436*f4a2713aSLionel Sambuc //-----------------------------------------//
437*f4a2713aSLionel Sambuc //  Acquired After (aa)
438*f4a2713aSLionel Sambuc //-----------------------------------------//
439*f4a2713aSLionel Sambuc 
440*f4a2713aSLionel Sambuc // FIXME: Would we like this attribute to take more than 1 arg?
441*f4a2713aSLionel Sambuc 
442*f4a2713aSLionel Sambuc #if !__has_attribute(acquired_after)
443*f4a2713aSLionel Sambuc #error "Should support acquired_after attribute"
444*f4a2713aSLionel Sambuc #endif
445*f4a2713aSLionel Sambuc 
446*f4a2713aSLionel Sambuc Mutex mu_aa ACQUIRED_AFTER(mu1);
447*f4a2713aSLionel Sambuc 
448*f4a2713aSLionel Sambuc Mutex aa_var_noargs __attribute__((acquired_after)); // \
449*f4a2713aSLionel Sambuc   // expected-error {{attribute takes at least 1 argument}}
450*f4a2713aSLionel Sambuc 
451*f4a2713aSLionel Sambuc class AAFoo {
452*f4a2713aSLionel Sambuc  private:
453*f4a2713aSLionel Sambuc   Mutex aa_field_noargs __attribute__((acquired_after)); // \
454*f4a2713aSLionel Sambuc     // expected-error {{attribute takes at least 1 argument}}
455*f4a2713aSLionel Sambuc   Mutex aa_field_args ACQUIRED_AFTER(mu1);
456*f4a2713aSLionel Sambuc };
457*f4a2713aSLionel Sambuc 
458*f4a2713aSLionel Sambuc class ACQUIRED_AFTER(mu1) AA { // \
459*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
460*f4a2713aSLionel Sambuc };
461*f4a2713aSLionel Sambuc 
462*f4a2713aSLionel Sambuc void aa_function() ACQUIRED_AFTER(mu1); // \
463*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
464*f4a2713aSLionel Sambuc 
465*f4a2713aSLionel Sambuc void aa_function_params(int gv_lvar ACQUIRED_AFTER(mu1)); // \
466*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
467*f4a2713aSLionel Sambuc 
468*f4a2713aSLionel Sambuc void aa_testfn(int y){
469*f4a2713aSLionel Sambuc   Mutex x ACQUIRED_AFTER(mu1) = Mutex(); // \
470*f4a2713aSLionel Sambuc     // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
471*f4a2713aSLionel Sambuc }
472*f4a2713aSLionel Sambuc 
473*f4a2713aSLionel Sambuc //Check argument parsing.
474*f4a2713aSLionel Sambuc 
475*f4a2713aSLionel Sambuc // legal attribute arguments
476*f4a2713aSLionel Sambuc Mutex aa_var_arg_1 ACQUIRED_AFTER(muWrapper.mu);
477*f4a2713aSLionel Sambuc Mutex aa_var_arg_2 ACQUIRED_AFTER(muDoubleWrapper.muWrapper->mu);
478*f4a2713aSLionel Sambuc Mutex aa_var_arg_3 ACQUIRED_AFTER(muWrapper.getMu());
479*f4a2713aSLionel Sambuc Mutex aa_var_arg_4 ACQUIRED_AFTER(*muWrapper.getMuPointer());
480*f4a2713aSLionel Sambuc Mutex aa_var_arg_5 ACQUIRED_AFTER(&mu1);
481*f4a2713aSLionel Sambuc Mutex aa_var_arg_6 ACQUIRED_AFTER(muRef);
482*f4a2713aSLionel Sambuc Mutex aa_var_arg_7 ACQUIRED_AFTER(muDoubleWrapper.getWrapper()->getMu());
483*f4a2713aSLionel Sambuc Mutex aa_var_arg_8 ACQUIRED_AFTER(muPointer);
484*f4a2713aSLionel Sambuc 
485*f4a2713aSLionel Sambuc 
486*f4a2713aSLionel Sambuc // illegal attribute arguments
487*f4a2713aSLionel Sambuc Mutex aa_var_arg_bad_1 ACQUIRED_AFTER(1); // \
488*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
489*f4a2713aSLionel Sambuc Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \
490*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}}
491*f4a2713aSLionel Sambuc Mutex aa_var_arg_bad_3 ACQUIRED_AFTER(muDoublePointer); // \
492*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
493*f4a2713aSLionel Sambuc Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \
494*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}}
495*f4a2713aSLionel Sambuc UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER(mu_aa); // \
496*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'lockable' attribute}}
497*f4a2713aSLionel Sambuc 
498*f4a2713aSLionel Sambuc //-----------------------------------------//
499*f4a2713aSLionel Sambuc //  Acquired Before (ab)
500*f4a2713aSLionel Sambuc //-----------------------------------------//
501*f4a2713aSLionel Sambuc 
502*f4a2713aSLionel Sambuc #if !__has_attribute(acquired_before)
503*f4a2713aSLionel Sambuc #error "Should support acquired_before attribute"
504*f4a2713aSLionel Sambuc #endif
505*f4a2713aSLionel Sambuc 
506*f4a2713aSLionel Sambuc Mutex mu_ab ACQUIRED_BEFORE(mu1);
507*f4a2713aSLionel Sambuc 
508*f4a2713aSLionel Sambuc Mutex ab_var_noargs __attribute__((acquired_before)); // \
509*f4a2713aSLionel Sambuc   // expected-error {{attribute takes at least 1 argument}}
510*f4a2713aSLionel Sambuc 
511*f4a2713aSLionel Sambuc class ABFoo {
512*f4a2713aSLionel Sambuc  private:
513*f4a2713aSLionel Sambuc   Mutex ab_field_noargs __attribute__((acquired_before)); // \
514*f4a2713aSLionel Sambuc     // expected-error {{attribute takes at least 1 argument}}
515*f4a2713aSLionel Sambuc   Mutex ab_field_args ACQUIRED_BEFORE(mu1);
516*f4a2713aSLionel Sambuc };
517*f4a2713aSLionel Sambuc 
518*f4a2713aSLionel Sambuc class ACQUIRED_BEFORE(mu1) AB { // \
519*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
520*f4a2713aSLionel Sambuc };
521*f4a2713aSLionel Sambuc 
522*f4a2713aSLionel Sambuc void ab_function() ACQUIRED_BEFORE(mu1); // \
523*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
524*f4a2713aSLionel Sambuc 
525*f4a2713aSLionel Sambuc void ab_function_params(int gv_lvar ACQUIRED_BEFORE(mu1)); // \
526*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
527*f4a2713aSLionel Sambuc 
528*f4a2713aSLionel Sambuc void ab_testfn(int y){
529*f4a2713aSLionel Sambuc   Mutex x ACQUIRED_BEFORE(mu1) = Mutex(); // \
530*f4a2713aSLionel Sambuc     // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
531*f4a2713aSLionel Sambuc }
532*f4a2713aSLionel Sambuc 
533*f4a2713aSLionel Sambuc // Note: illegal int ab_int ACQUIRED_BEFORE(mu1) will
534*f4a2713aSLionel Sambuc // be taken care of by warnings that ab__int is not lockable.
535*f4a2713aSLionel Sambuc 
536*f4a2713aSLionel Sambuc //Check argument parsing.
537*f4a2713aSLionel Sambuc 
538*f4a2713aSLionel Sambuc // legal attribute arguments
539*f4a2713aSLionel Sambuc Mutex ab_var_arg_1 ACQUIRED_BEFORE(muWrapper.mu);
540*f4a2713aSLionel Sambuc Mutex ab_var_arg_2 ACQUIRED_BEFORE(muDoubleWrapper.muWrapper->mu);
541*f4a2713aSLionel Sambuc Mutex ab_var_arg_3 ACQUIRED_BEFORE(muWrapper.getMu());
542*f4a2713aSLionel Sambuc Mutex ab_var_arg_4 ACQUIRED_BEFORE(*muWrapper.getMuPointer());
543*f4a2713aSLionel Sambuc Mutex ab_var_arg_5 ACQUIRED_BEFORE(&mu1);
544*f4a2713aSLionel Sambuc Mutex ab_var_arg_6 ACQUIRED_BEFORE(muRef);
545*f4a2713aSLionel Sambuc Mutex ab_var_arg_7 ACQUIRED_BEFORE(muDoubleWrapper.getWrapper()->getMu());
546*f4a2713aSLionel Sambuc Mutex ab_var_arg_8 ACQUIRED_BEFORE(muPointer);
547*f4a2713aSLionel Sambuc 
548*f4a2713aSLionel Sambuc 
549*f4a2713aSLionel Sambuc // illegal attribute arguments
550*f4a2713aSLionel Sambuc Mutex ab_var_arg_bad_1 ACQUIRED_BEFORE(1); // \
551*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
552*f4a2713aSLionel Sambuc Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \
553*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}}
554*f4a2713aSLionel Sambuc Mutex ab_var_arg_bad_3 ACQUIRED_BEFORE(muDoublePointer); // \
555*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
556*f4a2713aSLionel Sambuc Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \
557*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}}
558*f4a2713aSLionel Sambuc UnlockableMu ab_var_arg_bad_5 ACQUIRED_BEFORE(mu_ab); // \
559*f4a2713aSLionel Sambuc   // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'lockable' attribute}}
560*f4a2713aSLionel Sambuc 
561*f4a2713aSLionel Sambuc 
562*f4a2713aSLionel Sambuc //-----------------------------------------//
563*f4a2713aSLionel Sambuc //  Exclusive Lock Function (elf)
564*f4a2713aSLionel Sambuc //-----------------------------------------//
565*f4a2713aSLionel Sambuc 
566*f4a2713aSLionel Sambuc #if !__has_attribute(exclusive_lock_function)
567*f4a2713aSLionel Sambuc #error "Should support exclusive_lock_function attribute"
568*f4a2713aSLionel Sambuc #endif
569*f4a2713aSLionel Sambuc 
570*f4a2713aSLionel Sambuc // takes zero or more arguments, all locks (vars/fields)
571*f4a2713aSLionel Sambuc 
572*f4a2713aSLionel Sambuc void elf_function() EXCLUSIVE_LOCK_FUNCTION();
573*f4a2713aSLionel Sambuc 
574*f4a2713aSLionel Sambuc void elf_function_args() EXCLUSIVE_LOCK_FUNCTION(mu1, mu2);
575*f4a2713aSLionel Sambuc 
576*f4a2713aSLionel Sambuc int elf_testfn(int y) EXCLUSIVE_LOCK_FUNCTION();
577*f4a2713aSLionel Sambuc 
578*f4a2713aSLionel Sambuc int elf_testfn(int y) {
579*f4a2713aSLionel Sambuc   int x EXCLUSIVE_LOCK_FUNCTION() = y; // \
580*f4a2713aSLionel Sambuc     // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
581*f4a2713aSLionel Sambuc   return x;
582*f4a2713aSLionel Sambuc };
583*f4a2713aSLionel Sambuc 
584*f4a2713aSLionel Sambuc int elf_test_var EXCLUSIVE_LOCK_FUNCTION(); // \
585*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
586*f4a2713aSLionel Sambuc 
587*f4a2713aSLionel Sambuc class ElfFoo {
588*f4a2713aSLionel Sambuc  private:
589*f4a2713aSLionel Sambuc   int test_field EXCLUSIVE_LOCK_FUNCTION(); // \
590*f4a2713aSLionel Sambuc     // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
591*f4a2713aSLionel Sambuc   void test_method() EXCLUSIVE_LOCK_FUNCTION();
592*f4a2713aSLionel Sambuc };
593*f4a2713aSLionel Sambuc 
594*f4a2713aSLionel Sambuc class EXCLUSIVE_LOCK_FUNCTION() ElfTestClass { // \
595*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
596*f4a2713aSLionel Sambuc };
597*f4a2713aSLionel Sambuc 
598*f4a2713aSLionel Sambuc void elf_fun_params(int lvar EXCLUSIVE_LOCK_FUNCTION()); // \
599*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
600*f4a2713aSLionel Sambuc 
601*f4a2713aSLionel Sambuc // Check argument parsing.
602*f4a2713aSLionel Sambuc 
603*f4a2713aSLionel Sambuc // legal attribute arguments
604*f4a2713aSLionel Sambuc int elf_function_1() EXCLUSIVE_LOCK_FUNCTION(muWrapper.mu);
605*f4a2713aSLionel Sambuc int elf_function_2() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);
606*f4a2713aSLionel Sambuc int elf_function_3() EXCLUSIVE_LOCK_FUNCTION(muWrapper.getMu());
607*f4a2713aSLionel Sambuc int elf_function_4() EXCLUSIVE_LOCK_FUNCTION(*muWrapper.getMuPointer());
608*f4a2713aSLionel Sambuc int elf_function_5() EXCLUSIVE_LOCK_FUNCTION(&mu1);
609*f4a2713aSLionel Sambuc int elf_function_6() EXCLUSIVE_LOCK_FUNCTION(muRef);
610*f4a2713aSLionel Sambuc int elf_function_7() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());
611*f4a2713aSLionel Sambuc int elf_function_8() EXCLUSIVE_LOCK_FUNCTION(muPointer);
612*f4a2713aSLionel Sambuc int elf_function_9(Mutex x) EXCLUSIVE_LOCK_FUNCTION(1);
613*f4a2713aSLionel Sambuc int elf_function_9(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(1,2);
614*f4a2713aSLionel Sambuc 
615*f4a2713aSLionel Sambuc 
616*f4a2713aSLionel Sambuc // illegal attribute arguments
617*f4a2713aSLionel Sambuc int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \
618*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}}
619*f4a2713aSLionel Sambuc int elf_function_bad_3() EXCLUSIVE_LOCK_FUNCTION(muDoublePointer); // \
620*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}}
621*f4a2713aSLionel Sambuc int elf_function_bad_4() EXCLUSIVE_LOCK_FUNCTION(umu); // \
622*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
623*f4a2713aSLionel Sambuc 
624*f4a2713aSLionel Sambuc int elf_function_bad_1() EXCLUSIVE_LOCK_FUNCTION(1); // \
625*f4a2713aSLionel Sambuc   // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
626*f4a2713aSLionel Sambuc int elf_function_bad_5(Mutex x) EXCLUSIVE_LOCK_FUNCTION(0); // \
627*f4a2713aSLionel Sambuc   // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}
628*f4a2713aSLionel Sambuc int elf_function_bad_6(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(0); // \
629*f4a2713aSLionel Sambuc   // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}
630*f4a2713aSLionel Sambuc int elf_function_bad_7() EXCLUSIVE_LOCK_FUNCTION(0); // \
631*f4a2713aSLionel Sambuc   // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
632*f4a2713aSLionel Sambuc 
633*f4a2713aSLionel Sambuc 
634*f4a2713aSLionel Sambuc //-----------------------------------------//
635*f4a2713aSLionel Sambuc //  Shared Lock Function (slf)
636*f4a2713aSLionel Sambuc //-----------------------------------------//
637*f4a2713aSLionel Sambuc 
638*f4a2713aSLionel Sambuc #if !__has_attribute(shared_lock_function)
639*f4a2713aSLionel Sambuc #error "Should support shared_lock_function attribute"
640*f4a2713aSLionel Sambuc #endif
641*f4a2713aSLionel Sambuc 
642*f4a2713aSLionel Sambuc // takes zero or more arguments, all locks (vars/fields)
643*f4a2713aSLionel Sambuc 
644*f4a2713aSLionel Sambuc void slf_function() SHARED_LOCK_FUNCTION();
645*f4a2713aSLionel Sambuc 
646*f4a2713aSLionel Sambuc void slf_function_args() SHARED_LOCK_FUNCTION(mu1, mu2);
647*f4a2713aSLionel Sambuc 
648*f4a2713aSLionel Sambuc int slf_testfn(int y) SHARED_LOCK_FUNCTION();
649*f4a2713aSLionel Sambuc 
650*f4a2713aSLionel Sambuc int slf_testfn(int y) {
651*f4a2713aSLionel Sambuc   int x SHARED_LOCK_FUNCTION() = y; // \
652*f4a2713aSLionel Sambuc     // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
653*f4a2713aSLionel Sambuc   return x;
654*f4a2713aSLionel Sambuc };
655*f4a2713aSLionel Sambuc 
656*f4a2713aSLionel Sambuc int slf_test_var SHARED_LOCK_FUNCTION(); // \
657*f4a2713aSLionel Sambuc   // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
658*f4a2713aSLionel Sambuc 
659*f4a2713aSLionel Sambuc void slf_fun_params(int lvar SHARED_LOCK_FUNCTION()); // \
660*f4a2713aSLionel Sambuc   // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
661*f4a2713aSLionel Sambuc 
662*f4a2713aSLionel Sambuc class SlfFoo {
663*f4a2713aSLionel Sambuc  private:
664*f4a2713aSLionel Sambuc   int test_field SHARED_LOCK_FUNCTION(); // \
665*f4a2713aSLionel Sambuc     // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
666*f4a2713aSLionel Sambuc   void test_method() SHARED_LOCK_FUNCTION();
667*f4a2713aSLionel Sambuc };
668*f4a2713aSLionel Sambuc 
669*f4a2713aSLionel Sambuc class SHARED_LOCK_FUNCTION() SlfTestClass { // \
670*f4a2713aSLionel Sambuc   // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
671*f4a2713aSLionel Sambuc };
672*f4a2713aSLionel Sambuc 
673*f4a2713aSLionel Sambuc // Check argument parsing.
674*f4a2713aSLionel Sambuc 
675*f4a2713aSLionel Sambuc // legal attribute arguments
676*f4a2713aSLionel Sambuc int slf_function_1() SHARED_LOCK_FUNCTION(muWrapper.mu);
677*f4a2713aSLionel Sambuc int slf_function_2() SHARED_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);
678*f4a2713aSLionel Sambuc int slf_function_3() SHARED_LOCK_FUNCTION(muWrapper.getMu());
679*f4a2713aSLionel Sambuc int slf_function_4() SHARED_LOCK_FUNCTION(*muWrapper.getMuPointer());
680*f4a2713aSLionel Sambuc int slf_function_5() SHARED_LOCK_FUNCTION(&mu1);
681*f4a2713aSLionel Sambuc int slf_function_6() SHARED_LOCK_FUNCTION(muRef);
682*f4a2713aSLionel Sambuc int slf_function_7() SHARED_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());
683*f4a2713aSLionel Sambuc int slf_function_8() SHARED_LOCK_FUNCTION(muPointer);
684*f4a2713aSLionel Sambuc int slf_function_9(Mutex x) SHARED_LOCK_FUNCTION(1);
685*f4a2713aSLionel Sambuc int slf_function_9(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(1,2);
686*f4a2713aSLionel Sambuc 
687*f4a2713aSLionel Sambuc 
688*f4a2713aSLionel Sambuc // illegal attribute arguments
689*f4a2713aSLionel Sambuc int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \
690*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}}
691*f4a2713aSLionel Sambuc int slf_function_bad_3() SHARED_LOCK_FUNCTION(muDoublePointer); // \
692*f4a2713aSLionel Sambuc   // expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}}
693*f4a2713aSLionel Sambuc int slf_function_bad_4() SHARED_LOCK_FUNCTION(umu); // \
694*f4a2713aSLionel Sambuc   // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
695*f4a2713aSLionel Sambuc 
696*f4a2713aSLionel Sambuc int slf_function_bad_1() SHARED_LOCK_FUNCTION(1); // \
697*f4a2713aSLionel Sambuc   // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
698*f4a2713aSLionel Sambuc int slf_function_bad_5(Mutex x) SHARED_LOCK_FUNCTION(0); // \
699*f4a2713aSLionel Sambuc   // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}
700*f4a2713aSLionel Sambuc int slf_function_bad_6(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(0); // \
701*f4a2713aSLionel Sambuc   // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}
702*f4a2713aSLionel Sambuc int slf_function_bad_7() SHARED_LOCK_FUNCTION(0); // \
703*f4a2713aSLionel Sambuc   // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
704*f4a2713aSLionel Sambuc 
705*f4a2713aSLionel Sambuc 
706*f4a2713aSLionel Sambuc //-----------------------------------------//
707*f4a2713aSLionel Sambuc //  Exclusive TryLock Function (etf)
708*f4a2713aSLionel Sambuc //-----------------------------------------//
709*f4a2713aSLionel Sambuc 
710*f4a2713aSLionel Sambuc #if !__has_attribute(exclusive_trylock_function)
711*f4a2713aSLionel Sambuc #error "Should support exclusive_trylock_function attribute"
712*f4a2713aSLionel Sambuc #endif
713*f4a2713aSLionel Sambuc 
714*f4a2713aSLionel Sambuc // takes a mandatory boolean or integer argument specifying the retval
715*f4a2713aSLionel Sambuc // plus an optional list of locks (vars/fields)
716*f4a2713aSLionel Sambuc 
717*f4a2713aSLionel Sambuc void etf_function() __attribute__((exclusive_trylock_function));  // \
718*f4a2713aSLionel Sambuc   // expected-error {{attribute takes at least 1 argument}}
719*f4a2713aSLionel Sambuc 
720*f4a2713aSLionel Sambuc void etf_function_args() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu2);
721*f4a2713aSLionel Sambuc 
722*f4a2713aSLionel Sambuc void etf_function_arg() EXCLUSIVE_TRYLOCK_FUNCTION(1);
723*f4a2713aSLionel Sambuc 
724*f4a2713aSLionel Sambuc int etf_testfn(int y) EXCLUSIVE_TRYLOCK_FUNCTION(1);
725*f4a2713aSLionel Sambuc 
726*f4a2713aSLionel Sambuc int etf_testfn(int y) {
727*f4a2713aSLionel Sambuc   int x EXCLUSIVE_TRYLOCK_FUNCTION(1) = y; // \
728*f4a2713aSLionel Sambuc     // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
729*f4a2713aSLionel Sambuc   return x;
730*f4a2713aSLionel Sambuc };
731*f4a2713aSLionel Sambuc 
732*f4a2713aSLionel Sambuc int etf_test_var EXCLUSIVE_TRYLOCK_FUNCTION(1); // \
733*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
734*f4a2713aSLionel Sambuc 
735*f4a2713aSLionel Sambuc class EtfFoo {
736*f4a2713aSLionel Sambuc  private:
737*f4a2713aSLionel Sambuc   int test_field EXCLUSIVE_TRYLOCK_FUNCTION(1); // \
738*f4a2713aSLionel Sambuc     // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
739*f4a2713aSLionel Sambuc   void test_method() EXCLUSIVE_TRYLOCK_FUNCTION(1);
740*f4a2713aSLionel Sambuc };
741*f4a2713aSLionel Sambuc 
742*f4a2713aSLionel Sambuc class EXCLUSIVE_TRYLOCK_FUNCTION(1) EtfTestClass { // \
743*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
744*f4a2713aSLionel Sambuc };
745*f4a2713aSLionel Sambuc 
746*f4a2713aSLionel Sambuc void etf_fun_params(int lvar EXCLUSIVE_TRYLOCK_FUNCTION(1)); // \
747*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
748*f4a2713aSLionel Sambuc 
749*f4a2713aSLionel Sambuc // Check argument parsing.
750*f4a2713aSLionel Sambuc 
751*f4a2713aSLionel Sambuc // legal attribute arguments
752*f4a2713aSLionel Sambuc int etf_function_1() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.mu);
753*f4a2713aSLionel Sambuc int etf_function_2() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu);
754*f4a2713aSLionel Sambuc int etf_function_3() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.getMu());
755*f4a2713aSLionel Sambuc int etf_function_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer());
756*f4a2713aSLionel Sambuc int etf_function_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, &mu1);
757*f4a2713aSLionel Sambuc int etf_function_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, muRef);
758*f4a2713aSLionel Sambuc int etf_function_7() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu());
759*f4a2713aSLionel Sambuc int etf_functetfn_8() EXCLUSIVE_TRYLOCK_FUNCTION(1, muPointer);
760*f4a2713aSLionel Sambuc int etf_function_9() EXCLUSIVE_TRYLOCK_FUNCTION(true);
761*f4a2713aSLionel Sambuc 
762*f4a2713aSLionel Sambuc 
763*f4a2713aSLionel Sambuc // illegal attribute arguments
764*f4a2713aSLionel Sambuc int etf_function_bad_1() EXCLUSIVE_TRYLOCK_FUNCTION(mu1); // \
765*f4a2713aSLionel Sambuc   // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}}
766*f4a2713aSLionel Sambuc int etf_function_bad_2() EXCLUSIVE_TRYLOCK_FUNCTION("mu"); // \
767*f4a2713aSLionel Sambuc   // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}}
768*f4a2713aSLionel Sambuc int etf_function_bad_3() EXCLUSIVE_TRYLOCK_FUNCTION(muDoublePointer); // \
769*f4a2713aSLionel Sambuc   // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}}
770*f4a2713aSLionel Sambuc 
771*f4a2713aSLionel Sambuc int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \
772*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}
773*f4a2713aSLionel Sambuc int etf_function_bad_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoublePointer); // \
774*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}}
775*f4a2713aSLionel Sambuc int etf_function_bad_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, umu); // \
776*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
777*f4a2713aSLionel Sambuc 
778*f4a2713aSLionel Sambuc 
779*f4a2713aSLionel Sambuc //-----------------------------------------//
780*f4a2713aSLionel Sambuc //  Shared TryLock Function (stf)
781*f4a2713aSLionel Sambuc //-----------------------------------------//
782*f4a2713aSLionel Sambuc 
783*f4a2713aSLionel Sambuc #if !__has_attribute(shared_trylock_function)
784*f4a2713aSLionel Sambuc #error "Should support shared_trylock_function attribute"
785*f4a2713aSLionel Sambuc #endif
786*f4a2713aSLionel Sambuc 
787*f4a2713aSLionel Sambuc // takes a mandatory boolean or integer argument specifying the retval
788*f4a2713aSLionel Sambuc // plus an optional list of locks (vars/fields)
789*f4a2713aSLionel Sambuc 
790*f4a2713aSLionel Sambuc void stf_function() __attribute__((shared_trylock_function));  // \
791*f4a2713aSLionel Sambuc   // expected-error {{attribute takes at least 1 argument}}
792*f4a2713aSLionel Sambuc 
793*f4a2713aSLionel Sambuc void stf_function_args() SHARED_TRYLOCK_FUNCTION(1, mu2);
794*f4a2713aSLionel Sambuc 
795*f4a2713aSLionel Sambuc void stf_function_arg() SHARED_TRYLOCK_FUNCTION(1);
796*f4a2713aSLionel Sambuc 
797*f4a2713aSLionel Sambuc int stf_testfn(int y) SHARED_TRYLOCK_FUNCTION(1);
798*f4a2713aSLionel Sambuc 
799*f4a2713aSLionel Sambuc int stf_testfn(int y) {
800*f4a2713aSLionel Sambuc   int x SHARED_TRYLOCK_FUNCTION(1) = y; // \
801*f4a2713aSLionel Sambuc     // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
802*f4a2713aSLionel Sambuc   return x;
803*f4a2713aSLionel Sambuc };
804*f4a2713aSLionel Sambuc 
805*f4a2713aSLionel Sambuc int stf_test_var SHARED_TRYLOCK_FUNCTION(1); // \
806*f4a2713aSLionel Sambuc   // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
807*f4a2713aSLionel Sambuc 
808*f4a2713aSLionel Sambuc void stf_fun_params(int lvar SHARED_TRYLOCK_FUNCTION(1)); // \
809*f4a2713aSLionel Sambuc   // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
810*f4a2713aSLionel Sambuc 
811*f4a2713aSLionel Sambuc 
812*f4a2713aSLionel Sambuc class StfFoo {
813*f4a2713aSLionel Sambuc  private:
814*f4a2713aSLionel Sambuc   int test_field SHARED_TRYLOCK_FUNCTION(1); // \
815*f4a2713aSLionel Sambuc     // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
816*f4a2713aSLionel Sambuc   void test_method() SHARED_TRYLOCK_FUNCTION(1);
817*f4a2713aSLionel Sambuc };
818*f4a2713aSLionel Sambuc 
819*f4a2713aSLionel Sambuc class SHARED_TRYLOCK_FUNCTION(1) StfTestClass { // \
820*f4a2713aSLionel Sambuc     // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
821*f4a2713aSLionel Sambuc };
822*f4a2713aSLionel Sambuc 
823*f4a2713aSLionel Sambuc // Check argument parsing.
824*f4a2713aSLionel Sambuc 
825*f4a2713aSLionel Sambuc // legal attribute arguments
826*f4a2713aSLionel Sambuc int stf_function_1() SHARED_TRYLOCK_FUNCTION(1, muWrapper.mu);
827*f4a2713aSLionel Sambuc int stf_function_2() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu);
828*f4a2713aSLionel Sambuc int stf_function_3() SHARED_TRYLOCK_FUNCTION(1, muWrapper.getMu());
829*f4a2713aSLionel Sambuc int stf_function_4() SHARED_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer());
830*f4a2713aSLionel Sambuc int stf_function_5() SHARED_TRYLOCK_FUNCTION(1, &mu1);
831*f4a2713aSLionel Sambuc int stf_function_6() SHARED_TRYLOCK_FUNCTION(1, muRef);
832*f4a2713aSLionel Sambuc int stf_function_7() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu());
833*f4a2713aSLionel Sambuc int stf_function_8() SHARED_TRYLOCK_FUNCTION(1, muPointer);
834*f4a2713aSLionel Sambuc int stf_function_9() SHARED_TRYLOCK_FUNCTION(true);
835*f4a2713aSLionel Sambuc 
836*f4a2713aSLionel Sambuc 
837*f4a2713aSLionel Sambuc // illegal attribute arguments
838*f4a2713aSLionel Sambuc int stf_function_bad_1() SHARED_TRYLOCK_FUNCTION(mu1); // \
839*f4a2713aSLionel Sambuc   // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}}
840*f4a2713aSLionel Sambuc int stf_function_bad_2() SHARED_TRYLOCK_FUNCTION("mu"); // \
841*f4a2713aSLionel Sambuc   // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}}
842*f4a2713aSLionel Sambuc int stf_function_bad_3() SHARED_TRYLOCK_FUNCTION(muDoublePointer); // \
843*f4a2713aSLionel Sambuc   // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}}
844*f4a2713aSLionel Sambuc 
845*f4a2713aSLionel Sambuc int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \
846*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}
847*f4a2713aSLionel Sambuc int stf_function_bad_5() SHARED_TRYLOCK_FUNCTION(1, muDoublePointer); // \
848*f4a2713aSLionel Sambuc   // expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}}
849*f4a2713aSLionel Sambuc int stf_function_bad_6() SHARED_TRYLOCK_FUNCTION(1, umu); // \
850*f4a2713aSLionel Sambuc   // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
851*f4a2713aSLionel Sambuc 
852*f4a2713aSLionel Sambuc 
853*f4a2713aSLionel Sambuc //-----------------------------------------//
854*f4a2713aSLionel Sambuc //  Unlock Function (uf)
855*f4a2713aSLionel Sambuc //-----------------------------------------//
856*f4a2713aSLionel Sambuc 
857*f4a2713aSLionel Sambuc #if !__has_attribute(unlock_function)
858*f4a2713aSLionel Sambuc #error "Should support unlock_function attribute"
859*f4a2713aSLionel Sambuc #endif
860*f4a2713aSLionel Sambuc 
861*f4a2713aSLionel Sambuc // takes zero or more arguments, all locks (vars/fields)
862*f4a2713aSLionel Sambuc 
863*f4a2713aSLionel Sambuc void uf_function() UNLOCK_FUNCTION();
864*f4a2713aSLionel Sambuc 
865*f4a2713aSLionel Sambuc void uf_function_args() UNLOCK_FUNCTION(mu1, mu2);
866*f4a2713aSLionel Sambuc 
867*f4a2713aSLionel Sambuc int uf_testfn(int y) UNLOCK_FUNCTION();
868*f4a2713aSLionel Sambuc 
869*f4a2713aSLionel Sambuc int uf_testfn(int y) {
870*f4a2713aSLionel Sambuc   int x UNLOCK_FUNCTION() = y; // \
871*f4a2713aSLionel Sambuc     // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
872*f4a2713aSLionel Sambuc   return x;
873*f4a2713aSLionel Sambuc };
874*f4a2713aSLionel Sambuc 
875*f4a2713aSLionel Sambuc int uf_test_var UNLOCK_FUNCTION(); // \
876*f4a2713aSLionel Sambuc   // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
877*f4a2713aSLionel Sambuc 
878*f4a2713aSLionel Sambuc class UfFoo {
879*f4a2713aSLionel Sambuc  private:
880*f4a2713aSLionel Sambuc   int test_field UNLOCK_FUNCTION(); // \
881*f4a2713aSLionel Sambuc     // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
882*f4a2713aSLionel Sambuc   void test_method() UNLOCK_FUNCTION();
883*f4a2713aSLionel Sambuc };
884*f4a2713aSLionel Sambuc 
885*f4a2713aSLionel Sambuc class NO_THREAD_SAFETY_ANALYSIS UfTestClass { // \
886*f4a2713aSLionel Sambuc   // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
887*f4a2713aSLionel Sambuc };
888*f4a2713aSLionel Sambuc 
889*f4a2713aSLionel Sambuc void uf_fun_params(int lvar UNLOCK_FUNCTION()); // \
890*f4a2713aSLionel Sambuc   // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
891*f4a2713aSLionel Sambuc 
892*f4a2713aSLionel Sambuc // Check argument parsing.
893*f4a2713aSLionel Sambuc 
894*f4a2713aSLionel Sambuc // legal attribute arguments
895*f4a2713aSLionel Sambuc int uf_function_1() UNLOCK_FUNCTION(muWrapper.mu);
896*f4a2713aSLionel Sambuc int uf_function_2() UNLOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);
897*f4a2713aSLionel Sambuc int uf_function_3() UNLOCK_FUNCTION(muWrapper.getMu());
898*f4a2713aSLionel Sambuc int uf_function_4() UNLOCK_FUNCTION(*muWrapper.getMuPointer());
899*f4a2713aSLionel Sambuc int uf_function_5() UNLOCK_FUNCTION(&mu1);
900*f4a2713aSLionel Sambuc int uf_function_6() UNLOCK_FUNCTION(muRef);
901*f4a2713aSLionel Sambuc int uf_function_7() UNLOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());
902*f4a2713aSLionel Sambuc int uf_function_8() UNLOCK_FUNCTION(muPointer);
903*f4a2713aSLionel Sambuc int uf_function_9(Mutex x) UNLOCK_FUNCTION(1);
904*f4a2713aSLionel Sambuc int uf_function_9(Mutex x, Mutex y) UNLOCK_FUNCTION(1,2);
905*f4a2713aSLionel Sambuc 
906*f4a2713aSLionel Sambuc 
907*f4a2713aSLionel Sambuc // illegal attribute arguments
908*f4a2713aSLionel Sambuc int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \
909*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}}
910*f4a2713aSLionel Sambuc int uf_function_bad_3() UNLOCK_FUNCTION(muDoublePointer); // \
911*f4a2713aSLionel Sambuc   // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}}
912*f4a2713aSLionel Sambuc int uf_function_bad_4() UNLOCK_FUNCTION(umu); // \
913*f4a2713aSLionel Sambuc   // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
914*f4a2713aSLionel Sambuc 
915*f4a2713aSLionel Sambuc int uf_function_bad_1() UNLOCK_FUNCTION(1); // \
916*f4a2713aSLionel Sambuc   // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
917*f4a2713aSLionel Sambuc int uf_function_bad_5(Mutex x) UNLOCK_FUNCTION(0); // \
918*f4a2713aSLionel Sambuc   // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}
919*f4a2713aSLionel Sambuc int uf_function_bad_6(Mutex x, Mutex y) UNLOCK_FUNCTION(0); // \
920*f4a2713aSLionel Sambuc   // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}
921*f4a2713aSLionel Sambuc int uf_function_bad_7() UNLOCK_FUNCTION(0); // \
922*f4a2713aSLionel Sambuc   // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
923*f4a2713aSLionel Sambuc 
924*f4a2713aSLionel Sambuc 
925*f4a2713aSLionel Sambuc //-----------------------------------------//
926*f4a2713aSLionel Sambuc //  Lock Returned (lr)
927*f4a2713aSLionel Sambuc //-----------------------------------------//
928*f4a2713aSLionel Sambuc 
929*f4a2713aSLionel Sambuc #if !__has_attribute(lock_returned)
930*f4a2713aSLionel Sambuc #error "Should support lock_returned attribute"
931*f4a2713aSLionel Sambuc #endif
932*f4a2713aSLionel Sambuc 
933*f4a2713aSLionel Sambuc // Takes exactly one argument, a var/field
934*f4a2713aSLionel Sambuc 
935*f4a2713aSLionel Sambuc void lr_function() __attribute__((lock_returned)); // \
936*f4a2713aSLionel Sambuc   // expected-error {{'lock_returned' attribute takes one argument}}
937*f4a2713aSLionel Sambuc 
938*f4a2713aSLionel Sambuc void lr_function_arg() LOCK_RETURNED(mu1);
939*f4a2713aSLionel Sambuc 
940*f4a2713aSLionel Sambuc void lr_function_args() __attribute__((lock_returned(mu1, mu2))); // \
941*f4a2713aSLionel Sambuc   // expected-error {{'lock_returned' attribute takes one argument}}
942*f4a2713aSLionel Sambuc 
943*f4a2713aSLionel Sambuc int lr_testfn(int y) LOCK_RETURNED(mu1);
944*f4a2713aSLionel Sambuc 
945*f4a2713aSLionel Sambuc int lr_testfn(int y) {
946*f4a2713aSLionel Sambuc   int x LOCK_RETURNED(mu1) = y; // \
947*f4a2713aSLionel Sambuc     // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
948*f4a2713aSLionel Sambuc   return x;
949*f4a2713aSLionel Sambuc };
950*f4a2713aSLionel Sambuc 
951*f4a2713aSLionel Sambuc int lr_test_var LOCK_RETURNED(mu1); // \
952*f4a2713aSLionel Sambuc   // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
953*f4a2713aSLionel Sambuc 
954*f4a2713aSLionel Sambuc void lr_fun_params(int lvar LOCK_RETURNED(mu1)); // \
955*f4a2713aSLionel Sambuc   // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
956*f4a2713aSLionel Sambuc 
957*f4a2713aSLionel Sambuc class LrFoo {
958*f4a2713aSLionel Sambuc  private:
959*f4a2713aSLionel Sambuc   int test_field LOCK_RETURNED(mu1); // \
960*f4a2713aSLionel Sambuc     // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
961*f4a2713aSLionel Sambuc   void test_method() LOCK_RETURNED(mu1);
962*f4a2713aSLionel Sambuc };
963*f4a2713aSLionel Sambuc 
964*f4a2713aSLionel Sambuc class LOCK_RETURNED(mu1) LrTestClass { // \
965*f4a2713aSLionel Sambuc     // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
966*f4a2713aSLionel Sambuc };
967*f4a2713aSLionel Sambuc 
968*f4a2713aSLionel Sambuc // Check argument parsing.
969*f4a2713aSLionel Sambuc 
970*f4a2713aSLionel Sambuc // legal attribute arguments
971*f4a2713aSLionel Sambuc int lr_function_1() LOCK_RETURNED(muWrapper.mu);
972*f4a2713aSLionel Sambuc int lr_function_2() LOCK_RETURNED(muDoubleWrapper.muWrapper->mu);
973*f4a2713aSLionel Sambuc int lr_function_3() LOCK_RETURNED(muWrapper.getMu());
974*f4a2713aSLionel Sambuc int lr_function_4() LOCK_RETURNED(*muWrapper.getMuPointer());
975*f4a2713aSLionel Sambuc int lr_function_5() LOCK_RETURNED(&mu1);
976*f4a2713aSLionel Sambuc int lr_function_6() LOCK_RETURNED(muRef);
977*f4a2713aSLionel Sambuc int lr_function_7() LOCK_RETURNED(muDoubleWrapper.getWrapper()->getMu());
978*f4a2713aSLionel Sambuc int lr_function_8() LOCK_RETURNED(muPointer);
979*f4a2713aSLionel Sambuc 
980*f4a2713aSLionel Sambuc 
981*f4a2713aSLionel Sambuc // illegal attribute arguments
982*f4a2713aSLionel Sambuc int lr_function_bad_1() LOCK_RETURNED(1); // \
983*f4a2713aSLionel Sambuc   // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
984*f4a2713aSLionel Sambuc int lr_function_bad_2() LOCK_RETURNED("mu"); // \
985*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}}
986*f4a2713aSLionel Sambuc int lr_function_bad_3() LOCK_RETURNED(muDoublePointer); // \
987*f4a2713aSLionel Sambuc   // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
988*f4a2713aSLionel Sambuc int lr_function_bad_4() LOCK_RETURNED(umu); // \
989*f4a2713aSLionel Sambuc   // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'lockable' attribute}}
990*f4a2713aSLionel Sambuc 
991*f4a2713aSLionel Sambuc 
992*f4a2713aSLionel Sambuc 
993*f4a2713aSLionel Sambuc //-----------------------------------------//
994*f4a2713aSLionel Sambuc //  Locks Excluded (le)
995*f4a2713aSLionel Sambuc //-----------------------------------------//
996*f4a2713aSLionel Sambuc 
997*f4a2713aSLionel Sambuc #if !__has_attribute(locks_excluded)
998*f4a2713aSLionel Sambuc #error "Should support locks_excluded attribute"
999*f4a2713aSLionel Sambuc #endif
1000*f4a2713aSLionel Sambuc 
1001*f4a2713aSLionel Sambuc // takes one or more arguments, all locks (vars/fields)
1002*f4a2713aSLionel Sambuc 
1003*f4a2713aSLionel Sambuc void le_function() __attribute__((locks_excluded)); // \
1004*f4a2713aSLionel Sambuc   // expected-error {{attribute takes at least 1 argument}}
1005*f4a2713aSLionel Sambuc 
1006*f4a2713aSLionel Sambuc void le_function_arg() LOCKS_EXCLUDED(mu1);
1007*f4a2713aSLionel Sambuc 
1008*f4a2713aSLionel Sambuc void le_function_args() LOCKS_EXCLUDED(mu1, mu2);
1009*f4a2713aSLionel Sambuc 
1010*f4a2713aSLionel Sambuc int le_testfn(int y) LOCKS_EXCLUDED(mu1);
1011*f4a2713aSLionel Sambuc 
1012*f4a2713aSLionel Sambuc int le_testfn(int y) {
1013*f4a2713aSLionel Sambuc   int x LOCKS_EXCLUDED(mu1) = y; // \
1014*f4a2713aSLionel Sambuc     // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
1015*f4a2713aSLionel Sambuc   return x;
1016*f4a2713aSLionel Sambuc };
1017*f4a2713aSLionel Sambuc 
1018*f4a2713aSLionel Sambuc int le_test_var LOCKS_EXCLUDED(mu1); // \
1019*f4a2713aSLionel Sambuc   // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
1020*f4a2713aSLionel Sambuc 
1021*f4a2713aSLionel Sambuc void le_fun_params(int lvar LOCKS_EXCLUDED(mu1)); // \
1022*f4a2713aSLionel Sambuc   // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
1023*f4a2713aSLionel Sambuc 
1024*f4a2713aSLionel Sambuc class LeFoo {
1025*f4a2713aSLionel Sambuc  private:
1026*f4a2713aSLionel Sambuc   int test_field LOCKS_EXCLUDED(mu1); // \
1027*f4a2713aSLionel Sambuc     // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
1028*f4a2713aSLionel Sambuc   void test_method() LOCKS_EXCLUDED(mu1);
1029*f4a2713aSLionel Sambuc };
1030*f4a2713aSLionel Sambuc 
1031*f4a2713aSLionel Sambuc class LOCKS_EXCLUDED(mu1) LeTestClass { // \
1032*f4a2713aSLionel Sambuc   // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
1033*f4a2713aSLionel Sambuc };
1034*f4a2713aSLionel Sambuc 
1035*f4a2713aSLionel Sambuc // Check argument parsing.
1036*f4a2713aSLionel Sambuc 
1037*f4a2713aSLionel Sambuc // legal attribute arguments
1038*f4a2713aSLionel Sambuc int le_function_1() LOCKS_EXCLUDED(muWrapper.mu);
1039*f4a2713aSLionel Sambuc int le_function_2() LOCKS_EXCLUDED(muDoubleWrapper.muWrapper->mu);
1040*f4a2713aSLionel Sambuc int le_function_3() LOCKS_EXCLUDED(muWrapper.getMu());
1041*f4a2713aSLionel Sambuc int le_function_4() LOCKS_EXCLUDED(*muWrapper.getMuPointer());
1042*f4a2713aSLionel Sambuc int le_function_5() LOCKS_EXCLUDED(&mu1);
1043*f4a2713aSLionel Sambuc int le_function_6() LOCKS_EXCLUDED(muRef);
1044*f4a2713aSLionel Sambuc int le_function_7() LOCKS_EXCLUDED(muDoubleWrapper.getWrapper()->getMu());
1045*f4a2713aSLionel Sambuc int le_function_8() LOCKS_EXCLUDED(muPointer);
1046*f4a2713aSLionel Sambuc 
1047*f4a2713aSLionel Sambuc 
1048*f4a2713aSLionel Sambuc // illegal attribute arguments
1049*f4a2713aSLionel Sambuc int le_function_bad_1() LOCKS_EXCLUDED(1); // \
1050*f4a2713aSLionel Sambuc   // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
1051*f4a2713aSLionel Sambuc int le_function_bad_2() LOCKS_EXCLUDED("mu"); // \
1052*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}}
1053*f4a2713aSLionel Sambuc int le_function_bad_3() LOCKS_EXCLUDED(muDoublePointer); // \
1054*f4a2713aSLionel Sambuc   // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
1055*f4a2713aSLionel Sambuc int le_function_bad_4() LOCKS_EXCLUDED(umu); // \
1056*f4a2713aSLionel Sambuc   // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'lockable' attribute}}
1057*f4a2713aSLionel Sambuc 
1058*f4a2713aSLionel Sambuc 
1059*f4a2713aSLionel Sambuc 
1060*f4a2713aSLionel Sambuc //-----------------------------------------//
1061*f4a2713aSLionel Sambuc //  Exclusive Locks Required (elr)
1062*f4a2713aSLionel Sambuc //-----------------------------------------//
1063*f4a2713aSLionel Sambuc 
1064*f4a2713aSLionel Sambuc #if !__has_attribute(exclusive_locks_required)
1065*f4a2713aSLionel Sambuc #error "Should support exclusive_locks_required attribute"
1066*f4a2713aSLionel Sambuc #endif
1067*f4a2713aSLionel Sambuc 
1068*f4a2713aSLionel Sambuc // takes one or more arguments, all locks (vars/fields)
1069*f4a2713aSLionel Sambuc 
1070*f4a2713aSLionel Sambuc void elr_function() __attribute__((exclusive_locks_required)); // \
1071*f4a2713aSLionel Sambuc   // expected-error {{attribute takes at least 1 argument}}
1072*f4a2713aSLionel Sambuc 
1073*f4a2713aSLionel Sambuc void elr_function_arg() EXCLUSIVE_LOCKS_REQUIRED(mu1);
1074*f4a2713aSLionel Sambuc 
1075*f4a2713aSLionel Sambuc void elr_function_args() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2);
1076*f4a2713aSLionel Sambuc 
1077*f4a2713aSLionel Sambuc int elr_testfn(int y) EXCLUSIVE_LOCKS_REQUIRED(mu1);
1078*f4a2713aSLionel Sambuc 
1079*f4a2713aSLionel Sambuc int elr_testfn(int y) {
1080*f4a2713aSLionel Sambuc   int x EXCLUSIVE_LOCKS_REQUIRED(mu1) = y; // \
1081*f4a2713aSLionel Sambuc     // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
1082*f4a2713aSLionel Sambuc   return x;
1083*f4a2713aSLionel Sambuc };
1084*f4a2713aSLionel Sambuc 
1085*f4a2713aSLionel Sambuc int elr_test_var EXCLUSIVE_LOCKS_REQUIRED(mu1); // \
1086*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
1087*f4a2713aSLionel Sambuc 
1088*f4a2713aSLionel Sambuc void elr_fun_params(int lvar EXCLUSIVE_LOCKS_REQUIRED(mu1)); // \
1089*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
1090*f4a2713aSLionel Sambuc 
1091*f4a2713aSLionel Sambuc class ElrFoo {
1092*f4a2713aSLionel Sambuc  private:
1093*f4a2713aSLionel Sambuc   int test_field EXCLUSIVE_LOCKS_REQUIRED(mu1); // \
1094*f4a2713aSLionel Sambuc     // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
1095*f4a2713aSLionel Sambuc   void test_method() EXCLUSIVE_LOCKS_REQUIRED(mu1);
1096*f4a2713aSLionel Sambuc };
1097*f4a2713aSLionel Sambuc 
1098*f4a2713aSLionel Sambuc class EXCLUSIVE_LOCKS_REQUIRED(mu1) ElrTestClass { // \
1099*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
1100*f4a2713aSLionel Sambuc };
1101*f4a2713aSLionel Sambuc 
1102*f4a2713aSLionel Sambuc // Check argument parsing.
1103*f4a2713aSLionel Sambuc 
1104*f4a2713aSLionel Sambuc // legal attribute arguments
1105*f4a2713aSLionel Sambuc int elr_function_1() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.mu);
1106*f4a2713aSLionel Sambuc int elr_function_2() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu);
1107*f4a2713aSLionel Sambuc int elr_function_3() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.getMu());
1108*f4a2713aSLionel Sambuc int elr_function_4() EXCLUSIVE_LOCKS_REQUIRED(*muWrapper.getMuPointer());
1109*f4a2713aSLionel Sambuc int elr_function_5() EXCLUSIVE_LOCKS_REQUIRED(&mu1);
1110*f4a2713aSLionel Sambuc int elr_function_6() EXCLUSIVE_LOCKS_REQUIRED(muRef);
1111*f4a2713aSLionel Sambuc int elr_function_7() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu());
1112*f4a2713aSLionel Sambuc int elr_function_8() EXCLUSIVE_LOCKS_REQUIRED(muPointer);
1113*f4a2713aSLionel Sambuc 
1114*f4a2713aSLionel Sambuc 
1115*f4a2713aSLionel Sambuc // illegal attribute arguments
1116*f4a2713aSLionel Sambuc int elr_function_bad_1() EXCLUSIVE_LOCKS_REQUIRED(1); // \
1117*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
1118*f4a2713aSLionel Sambuc int elr_function_bad_2() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \
1119*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}}
1120*f4a2713aSLionel Sambuc int elr_function_bad_3() EXCLUSIVE_LOCKS_REQUIRED(muDoublePointer); // \
1121*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
1122*f4a2713aSLionel Sambuc int elr_function_bad_4() EXCLUSIVE_LOCKS_REQUIRED(umu); // \
1123*f4a2713aSLionel Sambuc   // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
1124*f4a2713aSLionel Sambuc 
1125*f4a2713aSLionel Sambuc 
1126*f4a2713aSLionel Sambuc 
1127*f4a2713aSLionel Sambuc 
1128*f4a2713aSLionel Sambuc //-----------------------------------------//
1129*f4a2713aSLionel Sambuc //  Shared Locks Required (slr)
1130*f4a2713aSLionel Sambuc //-----------------------------------------//
1131*f4a2713aSLionel Sambuc 
1132*f4a2713aSLionel Sambuc #if !__has_attribute(shared_locks_required)
1133*f4a2713aSLionel Sambuc #error "Should support shared_locks_required attribute"
1134*f4a2713aSLionel Sambuc #endif
1135*f4a2713aSLionel Sambuc 
1136*f4a2713aSLionel Sambuc // takes one or more arguments, all locks (vars/fields)
1137*f4a2713aSLionel Sambuc 
1138*f4a2713aSLionel Sambuc void slr_function() __attribute__((shared_locks_required)); // \
1139*f4a2713aSLionel Sambuc   // expected-error {{attribute takes at least 1 argument}}
1140*f4a2713aSLionel Sambuc 
1141*f4a2713aSLionel Sambuc void slr_function_arg() SHARED_LOCKS_REQUIRED(mu1);
1142*f4a2713aSLionel Sambuc 
1143*f4a2713aSLionel Sambuc void slr_function_args() SHARED_LOCKS_REQUIRED(mu1, mu2);
1144*f4a2713aSLionel Sambuc 
1145*f4a2713aSLionel Sambuc int slr_testfn(int y) SHARED_LOCKS_REQUIRED(mu1);
1146*f4a2713aSLionel Sambuc 
1147*f4a2713aSLionel Sambuc int slr_testfn(int y) {
1148*f4a2713aSLionel Sambuc   int x SHARED_LOCKS_REQUIRED(mu1) = y; // \
1149*f4a2713aSLionel Sambuc     // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
1150*f4a2713aSLionel Sambuc   return x;
1151*f4a2713aSLionel Sambuc };
1152*f4a2713aSLionel Sambuc 
1153*f4a2713aSLionel Sambuc int slr_test_var SHARED_LOCKS_REQUIRED(mu1); // \
1154*f4a2713aSLionel Sambuc   // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
1155*f4a2713aSLionel Sambuc 
1156*f4a2713aSLionel Sambuc void slr_fun_params(int lvar SHARED_LOCKS_REQUIRED(mu1)); // \
1157*f4a2713aSLionel Sambuc   // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
1158*f4a2713aSLionel Sambuc 
1159*f4a2713aSLionel Sambuc class SlrFoo {
1160*f4a2713aSLionel Sambuc  private:
1161*f4a2713aSLionel Sambuc   int test_field SHARED_LOCKS_REQUIRED(mu1); // \
1162*f4a2713aSLionel Sambuc     // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
1163*f4a2713aSLionel Sambuc   void test_method() SHARED_LOCKS_REQUIRED(mu1);
1164*f4a2713aSLionel Sambuc };
1165*f4a2713aSLionel Sambuc 
1166*f4a2713aSLionel Sambuc class SHARED_LOCKS_REQUIRED(mu1) SlrTestClass { // \
1167*f4a2713aSLionel Sambuc   // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
1168*f4a2713aSLionel Sambuc };
1169*f4a2713aSLionel Sambuc 
1170*f4a2713aSLionel Sambuc // Check argument parsing.
1171*f4a2713aSLionel Sambuc 
1172*f4a2713aSLionel Sambuc // legal attribute arguments
1173*f4a2713aSLionel Sambuc int slr_function_1() SHARED_LOCKS_REQUIRED(muWrapper.mu);
1174*f4a2713aSLionel Sambuc int slr_function_2() SHARED_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu);
1175*f4a2713aSLionel Sambuc int slr_function_3() SHARED_LOCKS_REQUIRED(muWrapper.getMu());
1176*f4a2713aSLionel Sambuc int slr_function_4() SHARED_LOCKS_REQUIRED(*muWrapper.getMuPointer());
1177*f4a2713aSLionel Sambuc int slr_function_5() SHARED_LOCKS_REQUIRED(&mu1);
1178*f4a2713aSLionel Sambuc int slr_function_6() SHARED_LOCKS_REQUIRED(muRef);
1179*f4a2713aSLionel Sambuc int slr_function_7() SHARED_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu());
1180*f4a2713aSLionel Sambuc int slr_function_8() SHARED_LOCKS_REQUIRED(muPointer);
1181*f4a2713aSLionel Sambuc 
1182*f4a2713aSLionel Sambuc 
1183*f4a2713aSLionel Sambuc // illegal attribute arguments
1184*f4a2713aSLionel Sambuc int slr_function_bad_1() SHARED_LOCKS_REQUIRED(1); // \
1185*f4a2713aSLionel Sambuc   // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
1186*f4a2713aSLionel Sambuc int slr_function_bad_2() SHARED_LOCKS_REQUIRED("mu"); // \
1187*f4a2713aSLionel Sambuc   // expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}}
1188*f4a2713aSLionel Sambuc int slr_function_bad_3() SHARED_LOCKS_REQUIRED(muDoublePointer); // \
1189*f4a2713aSLionel Sambuc   // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
1190*f4a2713aSLionel Sambuc int slr_function_bad_4() SHARED_LOCKS_REQUIRED(umu); // \
1191*f4a2713aSLionel Sambuc   // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
1192*f4a2713aSLionel Sambuc 
1193*f4a2713aSLionel Sambuc 
1194*f4a2713aSLionel Sambuc //-----------------------------------------//
1195*f4a2713aSLionel Sambuc //  Regression tests for unusual cases.
1196*f4a2713aSLionel Sambuc //-----------------------------------------//
1197*f4a2713aSLionel Sambuc 
1198*f4a2713aSLionel Sambuc int trivially_false_edges(bool b) {
1199*f4a2713aSLionel Sambuc   // Create NULL (never taken) edges in CFG
1200*f4a2713aSLionel Sambuc   if (false) return 1;
1201*f4a2713aSLionel Sambuc   else       return 2;
1202*f4a2713aSLionel Sambuc }
1203*f4a2713aSLionel Sambuc 
1204*f4a2713aSLionel Sambuc // Possible Clang bug -- method pointer in template parameter
1205*f4a2713aSLionel Sambuc class UnFoo {
1206*f4a2713aSLionel Sambuc public:
1207*f4a2713aSLionel Sambuc   void foo();
1208*f4a2713aSLionel Sambuc };
1209*f4a2713aSLionel Sambuc 
1210*f4a2713aSLionel Sambuc template<void (UnFoo::*methptr)()>
1211*f4a2713aSLionel Sambuc class MCaller {
1212*f4a2713aSLionel Sambuc public:
1213*f4a2713aSLionel Sambuc   static void call_method_ptr(UnFoo *f) {
1214*f4a2713aSLionel Sambuc     // FIXME: Possible Clang bug:
1215*f4a2713aSLionel Sambuc     // getCalleeDecl() returns NULL in the following case:
1216*f4a2713aSLionel Sambuc     (f->*methptr)();
1217*f4a2713aSLionel Sambuc   }
1218*f4a2713aSLionel Sambuc };
1219*f4a2713aSLionel Sambuc 
1220*f4a2713aSLionel Sambuc void call_method_ptr_inst(UnFoo* f) {
1221*f4a2713aSLionel Sambuc   MCaller<&UnFoo::foo>::call_method_ptr(f);
1222*f4a2713aSLionel Sambuc }
1223*f4a2713aSLionel Sambuc 
1224*f4a2713aSLionel Sambuc int temp;
1225*f4a2713aSLionel Sambuc void empty_back_edge() {
1226*f4a2713aSLionel Sambuc   // Create a back edge to a block with with no statements
1227*f4a2713aSLionel Sambuc   for (;;) {
1228*f4a2713aSLionel Sambuc     ++temp;
1229*f4a2713aSLionel Sambuc     if (temp > 10) break;
1230*f4a2713aSLionel Sambuc   }
1231*f4a2713aSLionel Sambuc }
1232*f4a2713aSLionel Sambuc 
1233*f4a2713aSLionel Sambuc struct Foomger {
1234*f4a2713aSLionel Sambuc   void operator++();
1235*f4a2713aSLionel Sambuc };
1236*f4a2713aSLionel Sambuc 
1237*f4a2713aSLionel Sambuc struct Foomgoper {
1238*f4a2713aSLionel Sambuc   Foomger f;
1239*f4a2713aSLionel Sambuc 
1240*f4a2713aSLionel Sambuc   bool done();
1241*f4a2713aSLionel Sambuc   void invalid_back_edge() {
1242*f4a2713aSLionel Sambuc     do {
1243*f4a2713aSLionel Sambuc       // FIXME: Possible Clang bug:
1244*f4a2713aSLionel Sambuc       // The first statement in this basic block has no source location
1245*f4a2713aSLionel Sambuc       ++f;
1246*f4a2713aSLionel Sambuc     } while (!done());
1247*f4a2713aSLionel Sambuc   }
1248*f4a2713aSLionel Sambuc };
1249*f4a2713aSLionel Sambuc 
1250*f4a2713aSLionel Sambuc 
1251*f4a2713aSLionel Sambuc //-----------------------------------------------------
1252*f4a2713aSLionel Sambuc // Parsing of member variables and function parameters
1253*f4a2713aSLionel Sambuc //------------------------------------------------------
1254*f4a2713aSLionel Sambuc 
1255*f4a2713aSLionel Sambuc Mutex gmu;
1256*f4a2713aSLionel Sambuc 
1257*f4a2713aSLionel Sambuc class StaticMu {
1258*f4a2713aSLionel Sambuc   static Mutex statmu;
1259*f4a2713aSLionel Sambuc };
1260*f4a2713aSLionel Sambuc 
1261*f4a2713aSLionel Sambuc class FooLate {
1262*f4a2713aSLionel Sambuc public:
1263*f4a2713aSLionel Sambuc   void foo1()           EXCLUSIVE_LOCKS_REQUIRED(gmu)   { }
1264*f4a2713aSLionel Sambuc   void foo2()           EXCLUSIVE_LOCKS_REQUIRED(mu)    { }
1265*f4a2713aSLionel Sambuc   void foo3(Mutex *m)   EXCLUSIVE_LOCKS_REQUIRED(m)     { }
1266*f4a2713aSLionel Sambuc   void foo3(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { }
1267*f4a2713aSLionel Sambuc   void foo4(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu);
1268*f4a2713aSLionel Sambuc 
1269*f4a2713aSLionel Sambuc   static void foo5()    EXCLUSIVE_LOCKS_REQUIRED(mu); // \
1270*f4a2713aSLionel Sambuc     // expected-error {{invalid use of member 'mu' in static member function}}
1271*f4a2713aSLionel Sambuc 
1272*f4a2713aSLionel Sambuc   template <class T>
1273*f4a2713aSLionel Sambuc   void foo6() EXCLUSIVE_LOCKS_REQUIRED(T::statmu) { }
1274*f4a2713aSLionel Sambuc 
1275*f4a2713aSLionel Sambuc   template <class T>
1276*f4a2713aSLionel Sambuc   void foo7(T* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { }
1277*f4a2713aSLionel Sambuc 
1278*f4a2713aSLionel Sambuc   int a GUARDED_BY(gmu);
1279*f4a2713aSLionel Sambuc   int b GUARDED_BY(mu);
1280*f4a2713aSLionel Sambuc   int c GUARDED_BY(this->mu);
1281*f4a2713aSLionel Sambuc 
1282*f4a2713aSLionel Sambuc   Mutex mu;
1283*f4a2713aSLionel Sambuc };
1284*f4a2713aSLionel Sambuc 
1285*f4a2713aSLionel Sambuc //-------------------------
1286*f4a2713aSLionel Sambuc // Empty argument lists
1287*f4a2713aSLionel Sambuc //-------------------------
1288*f4a2713aSLionel Sambuc 
1289*f4a2713aSLionel Sambuc class LOCKABLE EmptyArgListsTest {
1290*f4a2713aSLionel Sambuc   void lock() EXCLUSIVE_LOCK_FUNCTION() { }
1291*f4a2713aSLionel Sambuc   void unlock() UNLOCK_FUNCTION() { }
1292*f4a2713aSLionel Sambuc };
1293*f4a2713aSLionel Sambuc 
1294*f4a2713aSLionel Sambuc 
1295*f4a2713aSLionel Sambuc namespace FunctionDefinitionParseTest {
1296*f4a2713aSLionel Sambuc // Test parsing of attributes on function definitions.
1297*f4a2713aSLionel Sambuc 
1298*f4a2713aSLionel Sambuc class Foo {
1299*f4a2713aSLionel Sambuc public:
1300*f4a2713aSLionel Sambuc   Mutex mu_;
1301*f4a2713aSLionel Sambuc   void foo1();
1302*f4a2713aSLionel Sambuc   void foo2(Foo *f);
1303*f4a2713aSLionel Sambuc };
1304*f4a2713aSLionel Sambuc 
1305*f4a2713aSLionel Sambuc template <class T>
1306*f4a2713aSLionel Sambuc class Bar {
1307*f4a2713aSLionel Sambuc public:
1308*f4a2713aSLionel Sambuc   Mutex mu_;
1309*f4a2713aSLionel Sambuc   void bar();
1310*f4a2713aSLionel Sambuc };
1311*f4a2713aSLionel Sambuc 
1312*f4a2713aSLionel Sambuc void Foo::foo1()       EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
1313*f4a2713aSLionel Sambuc void Foo::foo2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { }
1314*f4a2713aSLionel Sambuc 
1315*f4a2713aSLionel Sambuc template <class T>
1316*f4a2713aSLionel Sambuc void Bar<T>::bar() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
1317*f4a2713aSLionel Sambuc 
1318*f4a2713aSLionel Sambuc void baz(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { }
1319*f4a2713aSLionel Sambuc 
1320*f4a2713aSLionel Sambuc } // end namespace
1321*f4a2713aSLionel Sambuc 
1322*f4a2713aSLionel Sambuc 
1323*f4a2713aSLionel Sambuc namespace TestMultiDecl {
1324*f4a2713aSLionel Sambuc 
1325*f4a2713aSLionel Sambuc class Foo {
1326*f4a2713aSLionel Sambuc public:
1327*f4a2713aSLionel Sambuc   int GUARDED_BY(mu_) a;
1328*f4a2713aSLionel Sambuc   int GUARDED_BY(mu_) b, c;
1329*f4a2713aSLionel Sambuc 
1330*f4a2713aSLionel Sambuc private:
1331*f4a2713aSLionel Sambuc   Mutex mu_;
1332*f4a2713aSLionel Sambuc };
1333*f4a2713aSLionel Sambuc 
1334*f4a2713aSLionel Sambuc } // end namespace TestMultiDecl
1335*f4a2713aSLionel Sambuc 
1336*f4a2713aSLionel Sambuc 
1337*f4a2713aSLionel Sambuc namespace NestedClassLateDecl {
1338*f4a2713aSLionel Sambuc 
1339*f4a2713aSLionel Sambuc class Foo {
1340*f4a2713aSLionel Sambuc   class Bar {
1341*f4a2713aSLionel Sambuc     int a GUARDED_BY(mu);
1342*f4a2713aSLionel Sambuc     int b GUARDED_BY(fooMuStatic);
1343*f4a2713aSLionel Sambuc 
1344*f4a2713aSLionel Sambuc     void bar()        EXCLUSIVE_LOCKS_REQUIRED(mu)       { a = 0;    }
1345*f4a2713aSLionel Sambuc     void bar2(Bar* b) EXCLUSIVE_LOCKS_REQUIRED(b->mu)    { b->a = 0; }
1346*f4a2713aSLionel Sambuc     void bar3(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->fooMu) { f->a = 0; }
1347*f4a2713aSLionel Sambuc 
1348*f4a2713aSLionel Sambuc     Mutex mu;
1349*f4a2713aSLionel Sambuc   };
1350*f4a2713aSLionel Sambuc 
1351*f4a2713aSLionel Sambuc   int a GUARDED_BY(fooMu);
1352*f4a2713aSLionel Sambuc   Mutex fooMu;
1353*f4a2713aSLionel Sambuc   static Mutex fooMuStatic;
1354*f4a2713aSLionel Sambuc };
1355*f4a2713aSLionel Sambuc 
1356*f4a2713aSLionel Sambuc }
1357*f4a2713aSLionel Sambuc 
1358*f4a2713aSLionel Sambuc namespace PointerToMemberTest {
1359*f4a2713aSLionel Sambuc 
1360*f4a2713aSLionel Sambuc // Empty string should be ignored.
1361*f4a2713aSLionel Sambuc int  testEmptyAttribute GUARDED_BY("");
1362*f4a2713aSLionel Sambuc void testEmptyAttributeFunction() EXCLUSIVE_LOCKS_REQUIRED("");
1363*f4a2713aSLionel Sambuc 
1364*f4a2713aSLionel Sambuc class Graph {
1365*f4a2713aSLionel Sambuc public:
1366*f4a2713aSLionel Sambuc   Mutex mu_;
1367*f4a2713aSLionel Sambuc 
1368*f4a2713aSLionel Sambuc   static Mutex* get_static_mu() LOCK_RETURNED(&Graph::mu_);
1369*f4a2713aSLionel Sambuc };
1370*f4a2713aSLionel Sambuc 
1371*f4a2713aSLionel Sambuc class Node {
1372*f4a2713aSLionel Sambuc public:
1373*f4a2713aSLionel Sambuc   void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_);
1374*f4a2713aSLionel Sambuc   int a GUARDED_BY(&Graph::mu_);
1375*f4a2713aSLionel Sambuc };
1376*f4a2713aSLionel Sambuc 
1377*f4a2713aSLionel Sambuc }
1378*f4a2713aSLionel Sambuc 
1379*f4a2713aSLionel Sambuc 
1380*f4a2713aSLionel Sambuc namespace SmartPointerTest {
1381*f4a2713aSLionel Sambuc 
1382*f4a2713aSLionel Sambuc template<class T>
1383*f4a2713aSLionel Sambuc class smart_ptr {
1384*f4a2713aSLionel Sambuc  public:
1385*f4a2713aSLionel Sambuc   T* operator->() { return ptr_; }
1386*f4a2713aSLionel Sambuc   T& operator*()  { return ptr_; }
1387*f4a2713aSLionel Sambuc 
1388*f4a2713aSLionel Sambuc  private:
1389*f4a2713aSLionel Sambuc   T* ptr_;
1390*f4a2713aSLionel Sambuc };
1391*f4a2713aSLionel Sambuc 
1392*f4a2713aSLionel Sambuc 
1393*f4a2713aSLionel Sambuc Mutex gmu;
1394*f4a2713aSLionel Sambuc smart_ptr<int> gdat PT_GUARDED_BY(gmu);
1395*f4a2713aSLionel Sambuc 
1396*f4a2713aSLionel Sambuc 
1397*f4a2713aSLionel Sambuc class MyClass {
1398*f4a2713aSLionel Sambuc public:
1399*f4a2713aSLionel Sambuc   Mutex mu_;
1400*f4a2713aSLionel Sambuc   smart_ptr<Mutex> smu_;
1401*f4a2713aSLionel Sambuc 
1402*f4a2713aSLionel Sambuc 
1403*f4a2713aSLionel Sambuc   smart_ptr<int> a PT_GUARDED_BY(mu_);
1404*f4a2713aSLionel Sambuc   int b            GUARDED_BY(smu_);
1405*f4a2713aSLionel Sambuc };
1406*f4a2713aSLionel Sambuc 
1407*f4a2713aSLionel Sambuc }
1408*f4a2713aSLionel Sambuc 
1409*f4a2713aSLionel Sambuc 
1410*f4a2713aSLionel Sambuc namespace InheritanceTest {
1411*f4a2713aSLionel Sambuc 
1412*f4a2713aSLionel Sambuc class LOCKABLE Base {
1413*f4a2713aSLionel Sambuc  public:
1414*f4a2713aSLionel Sambuc   void lock()   EXCLUSIVE_LOCK_FUNCTION();
1415*f4a2713aSLionel Sambuc   void unlock() UNLOCK_FUNCTION();
1416*f4a2713aSLionel Sambuc };
1417*f4a2713aSLionel Sambuc 
1418*f4a2713aSLionel Sambuc class Base2 { };
1419*f4a2713aSLionel Sambuc 
1420*f4a2713aSLionel Sambuc class Derived1 : public Base { };
1421*f4a2713aSLionel Sambuc 
1422*f4a2713aSLionel Sambuc class Derived2 : public Base2, public Derived1 { };
1423*f4a2713aSLionel Sambuc 
1424*f4a2713aSLionel Sambuc class Derived3 : public Base2 { };
1425*f4a2713aSLionel Sambuc 
1426*f4a2713aSLionel Sambuc class Foo {
1427*f4a2713aSLionel Sambuc   Derived1 mu1_;
1428*f4a2713aSLionel Sambuc   Derived2 mu2_;
1429*f4a2713aSLionel Sambuc   Derived3 mu3_;
1430*f4a2713aSLionel Sambuc   int a GUARDED_BY(mu1_);
1431*f4a2713aSLionel Sambuc   int b GUARDED_BY(mu2_);
1432*f4a2713aSLionel Sambuc   int c GUARDED_BY(mu3_);  // \
1433*f4a2713aSLionel Sambuc     // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class InheritanceTest::Derived3'}}
1434*f4a2713aSLionel Sambuc 
1435*f4a2713aSLionel Sambuc   void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1_, mu2_) {
1436*f4a2713aSLionel Sambuc     a = 0;
1437*f4a2713aSLionel Sambuc     b = 0;
1438*f4a2713aSLionel Sambuc   }
1439*f4a2713aSLionel Sambuc };
1440*f4a2713aSLionel Sambuc 
1441*f4a2713aSLionel Sambuc }
1442*f4a2713aSLionel Sambuc 
1443*f4a2713aSLionel Sambuc 
1444*f4a2713aSLionel Sambuc namespace InvalidDeclTest {
1445*f4a2713aSLionel Sambuc 
1446*f4a2713aSLionel Sambuc class Foo { };
1447*f4a2713aSLionel Sambuc namespace {
1448*f4a2713aSLionel Sambuc void Foo::bar(Mutex* mu) LOCKS_EXCLUDED(mu) { } // \
1449*f4a2713aSLionel Sambuc    // expected-error   {{cannot define or redeclare 'bar' here because namespace '' does not enclose namespace 'Foo'}} \
1450*f4a2713aSLionel Sambuc    // expected-warning {{attribute locks_excluded ignored, because it is not attached to a declaration}}
1451*f4a2713aSLionel Sambuc }
1452*f4a2713aSLionel Sambuc 
1453*f4a2713aSLionel Sambuc } // end namespace InvalidDeclTest
1454*f4a2713aSLionel Sambuc 
1455*f4a2713aSLionel Sambuc 
1456*f4a2713aSLionel Sambuc namespace StaticScopeTest {
1457*f4a2713aSLionel Sambuc 
1458*f4a2713aSLionel Sambuc class FooStream;
1459*f4a2713aSLionel Sambuc 
1460*f4a2713aSLionel Sambuc class Foo {
1461*f4a2713aSLionel Sambuc   mutable Mutex mu;
1462*f4a2713aSLionel Sambuc   int a GUARDED_BY(mu);
1463*f4a2713aSLionel Sambuc 
1464*f4a2713aSLionel Sambuc   static int si GUARDED_BY(mu); // \
1465*f4a2713aSLionel Sambuc     // expected-error {{invalid use of non-static data member 'mu'}}
1466*f4a2713aSLionel Sambuc 
1467*f4a2713aSLionel Sambuc   static void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \
1468*f4a2713aSLionel Sambuc     // expected-error {{invalid use of member 'mu' in static member function}}
1469*f4a2713aSLionel Sambuc 
1470*f4a2713aSLionel Sambuc   friend FooStream& operator<<(FooStream& s, const Foo& f)
1471*f4a2713aSLionel Sambuc     EXCLUSIVE_LOCKS_REQUIRED(mu); // \
1472*f4a2713aSLionel Sambuc     // expected-error {{invalid use of non-static data member 'mu'}}
1473*f4a2713aSLionel Sambuc };
1474*f4a2713aSLionel Sambuc 
1475*f4a2713aSLionel Sambuc 
1476*f4a2713aSLionel Sambuc } // end namespace StaticScopeTest
1477*f4a2713aSLionel Sambuc 
1478*f4a2713aSLionel Sambuc 
1479*f4a2713aSLionel Sambuc namespace FunctionAttributesInsideClass_ICE_Test {
1480*f4a2713aSLionel Sambuc 
1481*f4a2713aSLionel Sambuc class Foo {
1482*f4a2713aSLionel Sambuc public:
1483*f4a2713aSLionel Sambuc   /*  Originally found when parsing foo() as an ordinary method after the
1484*f4a2713aSLionel Sambuc    *  the following:
1485*f4a2713aSLionel Sambuc 
1486*f4a2713aSLionel Sambuc   template <class T>
1487*f4a2713aSLionel Sambuc   void syntaxErrorMethod(int i) {
1488*f4a2713aSLionel Sambuc     if (i) {
1489*f4a2713aSLionel Sambuc       foo(
1490*f4a2713aSLionel Sambuc     }
1491*f4a2713aSLionel Sambuc   }
1492*f4a2713aSLionel Sambuc   */
1493*f4a2713aSLionel Sambuc 
1494*f4a2713aSLionel Sambuc   void method() {
1495*f4a2713aSLionel Sambuc     void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \
1496*f4a2713aSLionel Sambuc       // expected-error {{use of undeclared identifier 'mu'}}
1497*f4a2713aSLionel Sambuc   }
1498*f4a2713aSLionel Sambuc };
1499*f4a2713aSLionel Sambuc 
1500*f4a2713aSLionel Sambuc }  // end namespace FunctionAttributesInsideClass_ICE_Test
1501*f4a2713aSLionel Sambuc 
1502