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