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