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