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 LOCKABLE Mutex {
26  public:
27  void Lock();
28};
29
30class UnlockableMu{
31};
32
33class MuWrapper {
34  public:
35  Mutex mu;
36  Mutex getMu() {
37    return mu;
38  }
39  Mutex * getMuPointer() {
40    return μ
41  }
42};
43
44
45class MuDoubleWrapper {
46  public:
47  MuWrapper* muWrapper;
48  MuWrapper* getWrapper() {
49    return muWrapper;
50  }
51};
52
53Mutex mu1;
54UnlockableMu umu;
55Mutex mu2;
56MuWrapper muWrapper;
57MuDoubleWrapper muDoubleWrapper;
58Mutex* muPointer;
59Mutex** muDoublePointer = & muPointer;
60Mutex& muRef = mu1;
61
62//---------------------------------------//
63// Scoping tests
64//--------------------------------------//
65
66class Foo {
67  Mutex foomu;
68  void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu);
69};
70
71class Foo2 {
72  void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu);
73  Mutex foomu;
74};
75
76class Bar {
77 Mutex barmu;
78 Mutex barmu2 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() 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) NO_THREAD_SAFETY_ANALYSIS;
99
100int noanal_testfn(int y) {
101  int x 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 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 NO_THREAD_SAFETY_ANALYSIS; // \
112    // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
113  void test_method() NO_THREAD_SAFETY_ANALYSIS;
114};
115
116class 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 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 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 GUARDED_VAR;
140  int gv_field_args __attribute__((guarded_var(1))); // \
141    // expected-error {{attribute takes no arguments}}
142};
143
144class GUARDED_VAR GV { // \
145  // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
146};
147
148void gv_function() GUARDED_VAR; // \
149  // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
150
151void gv_function_params(int gv_lvar GUARDED_VAR); // \
152  // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
153
154int gv_testfn(int y){
155  int x 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 PT_GUARDED_VAR;
171
172int pgv_var_noargs 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 PT_GUARDED_VAR;
178  int field_noargs 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 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() 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 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 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 LOCKABLE LTestClass {
215};
216
217class __attribute__((lockable (1))) LTestClass_args { // \
218    // expected-error {{attribute takes no arguments}}
219};
220
221void l_test_function() LOCKABLE;  // \
222  // expected-warning {{'lockable' attribute only applies to classes}}
223
224int l_testfn(int y) {
225  int x LOCKABLE = y; // \
226    // expected-warning {{'lockable' attribute only applies to classes}}
227  return x;
228}
229
230int l_test_var LOCKABLE; // \
231  // expected-warning {{'lockable' attribute only applies to classes}}
232
233class LFoo {
234 private:
235  int test_field LOCKABLE; // \
236    // expected-warning {{'lockable' attribute only applies to classes}}
237  void test_method() LOCKABLE; // \
238    // expected-warning {{'lockable' attribute only applies to classes}}
239};
240
241
242void l_function_params(int lvar 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 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() SCOPED_LOCKABLE;  // \
262  // expected-warning {{'scoped_lockable' attribute only applies to classes}}
263
264int sl_testfn(int y) {
265  int x SCOPED_LOCKABLE = y; // \
266    // expected-warning {{'scoped_lockable' attribute only applies to classes}}
267  return x;
268}
269
270int sl_test_var SCOPED_LOCKABLE; // \
271  // expected-warning {{'scoped_lockable' attribute only applies to classes}}
272
273class SLFoo {
274 private:
275  int test_field SCOPED_LOCKABLE; // \
276    // expected-warning {{'scoped_lockable' attribute only applies to classes}}
277  void test_method() SCOPED_LOCKABLE; // \
278    // expected-warning {{'scoped_lockable' attribute only applies to classes}}
279};
280
281
282void sl_function_params(int lvar 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 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 GUARDED_BY(mu1);
311};
312
313class GUARDED_BY(mu1) GB { // \
314  // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
315};
316
317void gb_function() GUARDED_BY(mu1); // \
318  // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
319
320void gb_function_params(int gv_lvar 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 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 GUARDED_BY(muWrapper.mu);
333int gb_var_arg_2 GUARDED_BY(muDoubleWrapper.muWrapper->mu);
334int gb_var_arg_3 GUARDED_BY(muWrapper.getMu());
335int gb_var_arg_4 GUARDED_BY(*muWrapper.getMuPointer());
336int gb_var_arg_5 GUARDED_BY(&mu1);
337int gb_var_arg_6 GUARDED_BY(muRef);
338int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());
339int gb_var_arg_8 GUARDED_BY(muPointer);
340
341
342// illegal attribute arguments
343int gb_var_arg_bad_1 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 GUARDED_BY("mu"); // \
346  // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
347int gb_var_arg_bad_3 GUARDED_BY(muDoublePointer); // \
348  // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'class Mutex **'}}
349int gb_var_arg_bad_4 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 PT_GUARDED_BY(mu1);
370
371int *pgb_ptr_var_args __attribute__((pt_guarded_by(mu1, mu2))); // \
372  // expected-error {{attribute takes one argument}}
373
374int pgb_var_args 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 PT_GUARDED_BY(mu1);
382};
383
384class PT_GUARDED_BY(mu1) PGB { // \
385  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
386};
387
388void pgb_function() 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 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 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 PT_GUARDED_BY(muWrapper.mu);
404int * pgb_var_arg_2 PT_GUARDED_BY(muDoubleWrapper.muWrapper->mu);
405int * pgb_var_arg_3 PT_GUARDED_BY(muWrapper.getMu());
406int * pgb_var_arg_4 PT_GUARDED_BY(*muWrapper.getMuPointer());
407int * pgb_var_arg_5 PT_GUARDED_BY(&mu1);
408int * pgb_var_arg_6 PT_GUARDED_BY(muRef);
409int * pgb_var_arg_7 PT_GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());
410int * pgb_var_arg_8 PT_GUARDED_BY(muPointer);
411
412
413// illegal attribute arguments
414int * pgb_var_arg_bad_1 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 PT_GUARDED_BY("mu"); // \
417  // expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}}
418int * pgb_var_arg_bad_3 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 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
434Mutex mu_aa ACQUIRED_AFTER(mu1);
435
436Mutex aa_var_noargs __attribute__((acquired_after)); // \
437  // expected-error {{attribute takes at least 1 argument}}
438
439class AAFoo {
440 private:
441  Mutex aa_field_noargs __attribute__((acquired_after)); // \
442    // expected-error {{attribute takes at least 1 argument}}
443  Mutex aa_field_args ACQUIRED_AFTER(mu1);
444};
445
446class ACQUIRED_AFTER(mu1) AA { // \
447  // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
448};
449
450void aa_function() ACQUIRED_AFTER(mu1); // \
451  // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
452
453void aa_function_params(int gv_lvar ACQUIRED_AFTER(mu1)); // \
454  // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
455
456void aa_testfn(int y){
457  Mutex x ACQUIRED_AFTER(mu1) = Mutex(); // \
458    // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
459}
460
461//Check argument parsing.
462
463// legal attribute arguments
464Mutex aa_var_arg_1 ACQUIRED_AFTER(muWrapper.mu);
465Mutex aa_var_arg_2 ACQUIRED_AFTER(muDoubleWrapper.muWrapper->mu);
466Mutex aa_var_arg_3 ACQUIRED_AFTER(muWrapper.getMu());
467Mutex aa_var_arg_4 ACQUIRED_AFTER(*muWrapper.getMuPointer());
468Mutex aa_var_arg_5 ACQUIRED_AFTER(&mu1);
469Mutex aa_var_arg_6 ACQUIRED_AFTER(muRef);
470Mutex aa_var_arg_7 ACQUIRED_AFTER(muDoubleWrapper.getWrapper()->getMu());
471Mutex aa_var_arg_8 ACQUIRED_AFTER(muPointer);
472
473
474// illegal attribute arguments
475Mutex aa_var_arg_bad_1 ACQUIRED_AFTER(1); // \
476  // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
477Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \
478  // expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}}
479Mutex aa_var_arg_bad_3 ACQUIRED_AFTER(muDoublePointer); // \
480  // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
481Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \
482  // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}}
483UnlockableMu aa_var_arg_bad_5 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
494Mutex mu_ab ACQUIRED_BEFORE(mu1);
495
496Mutex ab_var_noargs __attribute__((acquired_before)); // \
497  // expected-error {{attribute takes at least 1 argument}}
498
499class ABFoo {
500 private:
501  Mutex ab_field_noargs __attribute__((acquired_before)); // \
502    // expected-error {{attribute takes at least 1 argument}}
503  Mutex ab_field_args ACQUIRED_BEFORE(mu1);
504};
505
506class ACQUIRED_BEFORE(mu1) AB { // \
507  // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
508};
509
510void ab_function() ACQUIRED_BEFORE(mu1); // \
511  // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
512
513void ab_function_params(int gv_lvar ACQUIRED_BEFORE(mu1)); // \
514  // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
515
516void ab_testfn(int y){
517  Mutex x ACQUIRED_BEFORE(mu1) = Mutex(); // \
518    // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
519}
520
521// Note: illegal int ab_int 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
527Mutex ab_var_arg_1 ACQUIRED_BEFORE(muWrapper.mu);
528Mutex ab_var_arg_2 ACQUIRED_BEFORE(muDoubleWrapper.muWrapper->mu);
529Mutex ab_var_arg_3 ACQUIRED_BEFORE(muWrapper.getMu());
530Mutex ab_var_arg_4 ACQUIRED_BEFORE(*muWrapper.getMuPointer());
531Mutex ab_var_arg_5 ACQUIRED_BEFORE(&mu1);
532Mutex ab_var_arg_6 ACQUIRED_BEFORE(muRef);
533Mutex ab_var_arg_7 ACQUIRED_BEFORE(muDoubleWrapper.getWrapper()->getMu());
534Mutex ab_var_arg_8 ACQUIRED_BEFORE(muPointer);
535
536
537// illegal attribute arguments
538Mutex ab_var_arg_bad_1 ACQUIRED_BEFORE(1); // \
539  // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
540Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \
541  // expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}}
542Mutex ab_var_arg_bad_3 ACQUIRED_BEFORE(muDoublePointer); // \
543  // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
544Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \
545  // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}}
546UnlockableMu ab_var_arg_bad_5 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() EXCLUSIVE_LOCK_FUNCTION();
561
562void elf_function_args() EXCLUSIVE_LOCK_FUNCTION(mu1, mu2);
563
564int elf_testfn(int y) EXCLUSIVE_LOCK_FUNCTION();
565
566int elf_testfn(int y) {
567  int x 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 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 EXCLUSIVE_LOCK_FUNCTION(); // \
578    // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
579  void test_method() EXCLUSIVE_LOCK_FUNCTION();
580};
581
582class 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 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() EXCLUSIVE_LOCK_FUNCTION(muWrapper.mu);
593int elf_function_2() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);
594int elf_function_3() EXCLUSIVE_LOCK_FUNCTION(muWrapper.getMu());
595int elf_function_4() EXCLUSIVE_LOCK_FUNCTION(*muWrapper.getMuPointer());
596int elf_function_5() EXCLUSIVE_LOCK_FUNCTION(&mu1);
597int elf_function_6() EXCLUSIVE_LOCK_FUNCTION(muRef);
598int elf_function_7() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());
599int elf_function_8() EXCLUSIVE_LOCK_FUNCTION(muPointer);
600int elf_function_9(Mutex x) EXCLUSIVE_LOCK_FUNCTION(1);
601int elf_function_9(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(1,2);
602
603
604// illegal attribute arguments
605int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \
606  // expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}}
607int elf_function_bad_3() 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() 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() 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(Mutex x) 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(Mutex x, Mutex y) 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() 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() SHARED_LOCK_FUNCTION();
633
634void slf_function_args() SHARED_LOCK_FUNCTION(mu1, mu2);
635
636int slf_testfn(int y) SHARED_LOCK_FUNCTION();
637
638int slf_testfn(int y) {
639  int x 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 SHARED_LOCK_FUNCTION(); // \
645  // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
646
647void slf_fun_params(int lvar 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 SHARED_LOCK_FUNCTION(); // \
653    // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
654  void test_method() SHARED_LOCK_FUNCTION();
655};
656
657class 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() SHARED_LOCK_FUNCTION(muWrapper.mu);
665int slf_function_2() SHARED_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);
666int slf_function_3() SHARED_LOCK_FUNCTION(muWrapper.getMu());
667int slf_function_4() SHARED_LOCK_FUNCTION(*muWrapper.getMuPointer());
668int slf_function_5() SHARED_LOCK_FUNCTION(&mu1);
669int slf_function_6() SHARED_LOCK_FUNCTION(muRef);
670int slf_function_7() SHARED_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());
671int slf_function_8() SHARED_LOCK_FUNCTION(muPointer);
672int slf_function_9(Mutex x) SHARED_LOCK_FUNCTION(1);
673int slf_function_9(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(1,2);
674
675
676// illegal attribute arguments
677int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \
678  // expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}}
679int slf_function_bad_3() 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() 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() 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(Mutex x) 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(Mutex x, Mutex y) 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() 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() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu2);
709
710void etf_function_arg() EXCLUSIVE_TRYLOCK_FUNCTION(1);
711
712int etf_testfn(int y) EXCLUSIVE_TRYLOCK_FUNCTION(1);
713
714int etf_testfn(int y) {
715  int x 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 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 EXCLUSIVE_TRYLOCK_FUNCTION(1); // \
726    // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
727  void test_method() EXCLUSIVE_TRYLOCK_FUNCTION(1);
728};
729
730class 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 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() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.mu);
741int etf_function_2() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu);
742int etf_function_3() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.getMu());
743int etf_function_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer());
744int etf_function_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, &mu1);
745int etf_function_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, muRef);
746int etf_function_7() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu());
747int etf_functetfn_8() EXCLUSIVE_TRYLOCK_FUNCTION(1, muPointer);
748int etf_function_9() EXCLUSIVE_TRYLOCK_FUNCTION(true);
749
750
751// illegal attribute arguments
752int etf_function_bad_1() 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() 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() 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() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \
760  // expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}
761int etf_function_bad_5() 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() 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() SHARED_TRYLOCK_FUNCTION(1, mu2);
782
783void stf_function_arg() SHARED_TRYLOCK_FUNCTION(1);
784
785int stf_testfn(int y) SHARED_TRYLOCK_FUNCTION(1);
786
787int stf_testfn(int y) {
788  int x 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 SHARED_TRYLOCK_FUNCTION(1); // \
794  // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
795
796void stf_fun_params(int lvar 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 SHARED_TRYLOCK_FUNCTION(1); // \
803    // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
804  void test_method() SHARED_TRYLOCK_FUNCTION(1);
805};
806
807class 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() SHARED_TRYLOCK_FUNCTION(1, muWrapper.mu);
815int stf_function_2() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu);
816int stf_function_3() SHARED_TRYLOCK_FUNCTION(1, muWrapper.getMu());
817int stf_function_4() SHARED_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer());
818int stf_function_5() SHARED_TRYLOCK_FUNCTION(1, &mu1);
819int stf_function_6() SHARED_TRYLOCK_FUNCTION(1, muRef);
820int stf_function_7() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu());
821int stf_function_8() SHARED_TRYLOCK_FUNCTION(1, muPointer);
822int stf_function_9() SHARED_TRYLOCK_FUNCTION(true);
823
824
825// illegal attribute arguments
826int stf_function_bad_1() 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() 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() 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() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \
834  // expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}
835int stf_function_bad_5() 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() 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() UNLOCK_FUNCTION();
852
853void uf_function_args() UNLOCK_FUNCTION(mu1, mu2);
854
855int uf_testfn(int y) UNLOCK_FUNCTION();
856
857int uf_testfn(int y) {
858  int x UNLOCK_FUNCTION() = y; // \
859    // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
860  return x;
861};
862
863int uf_test_var UNLOCK_FUNCTION(); // \
864  // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
865
866class UfFoo {
867 private:
868  int test_field UNLOCK_FUNCTION(); // \
869    // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
870  void test_method() UNLOCK_FUNCTION();
871};
872
873class 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 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() UNLOCK_FUNCTION(muWrapper.mu);
884int uf_function_2() UNLOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);
885int uf_function_3() UNLOCK_FUNCTION(muWrapper.getMu());
886int uf_function_4() UNLOCK_FUNCTION(*muWrapper.getMuPointer());
887int uf_function_5() UNLOCK_FUNCTION(&mu1);
888int uf_function_6() UNLOCK_FUNCTION(muRef);
889int uf_function_7() UNLOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());
890int uf_function_8() UNLOCK_FUNCTION(muPointer);
891int uf_function_9(Mutex x) UNLOCK_FUNCTION(1);
892int uf_function_9(Mutex x, Mutex y) UNLOCK_FUNCTION(1,2);
893
894
895// illegal attribute arguments
896int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \
897  // expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}}
898int uf_function_bad_3() 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() UNLOCK_FUNCTION(umu); // \
901  // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
902
903int uf_function_bad_1() 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(Mutex x) 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(Mutex x, Mutex y) 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() 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() 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) LOCK_RETURNED(mu1);
932
933int lr_testfn(int y) {
934  int x 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 LOCK_RETURNED(mu1); // \
940  // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
941
942void lr_fun_params(int lvar LOCK_RETURNED(mu1)); // \
943  // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
944
945class LrFoo {
946 private:
947  int test_field LOCK_RETURNED(mu1); // \
948    // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
949  void test_method() LOCK_RETURNED(mu1);
950};
951
952class 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() LOCK_RETURNED(muWrapper.mu);
960int lr_function_2() LOCK_RETURNED(muDoubleWrapper.muWrapper->mu);
961int lr_function_3() LOCK_RETURNED(muWrapper.getMu());
962int lr_function_4() LOCK_RETURNED(*muWrapper.getMuPointer());
963int lr_function_5() LOCK_RETURNED(&mu1);
964int lr_function_6() LOCK_RETURNED(muRef);
965int lr_function_7() LOCK_RETURNED(muDoubleWrapper.getWrapper()->getMu());
966int lr_function_8() LOCK_RETURNED(muPointer);
967
968
969// illegal attribute arguments
970int lr_function_bad_1() 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() LOCK_RETURNED("mu"); // \
973  // expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}}
974int lr_function_bad_3() 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() 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() LOCKS_EXCLUDED(mu1);
995
996void le_function_args() LOCKS_EXCLUDED(mu1, mu2);
997
998int le_testfn(int y) LOCKS_EXCLUDED(mu1);
999
1000int le_testfn(int y) {
1001  int x 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 LOCKS_EXCLUDED(mu1); // \
1007  // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
1008
1009void le_fun_params(int lvar LOCKS_EXCLUDED(mu1)); // \
1010  // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
1011
1012class LeFoo {
1013 private:
1014  int test_field LOCKS_EXCLUDED(mu1); // \
1015    // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
1016  void test_method() LOCKS_EXCLUDED(mu1);
1017};
1018
1019class 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() LOCKS_EXCLUDED(muWrapper.mu);
1027int le_function_2() LOCKS_EXCLUDED(muDoubleWrapper.muWrapper->mu);
1028int le_function_3() LOCKS_EXCLUDED(muWrapper.getMu());
1029int le_function_4() LOCKS_EXCLUDED(*muWrapper.getMuPointer());
1030int le_function_5() LOCKS_EXCLUDED(&mu1);
1031int le_function_6() LOCKS_EXCLUDED(muRef);
1032int le_function_7() LOCKS_EXCLUDED(muDoubleWrapper.getWrapper()->getMu());
1033int le_function_8() LOCKS_EXCLUDED(muPointer);
1034
1035
1036// illegal attribute arguments
1037int le_function_bad_1() 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() LOCKS_EXCLUDED("mu"); // \
1040  // expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}}
1041int le_function_bad_3() 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() 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() EXCLUSIVE_LOCKS_REQUIRED(mu1);
1062
1063void elr_function_args() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2);
1064
1065int elr_testfn(int y) EXCLUSIVE_LOCKS_REQUIRED(mu1);
1066
1067int elr_testfn(int y) {
1068  int x 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 EXCLUSIVE_LOCKS_REQUIRED(mu1); // \
1074  // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
1075
1076void elr_fun_params(int lvar 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 EXCLUSIVE_LOCKS_REQUIRED(mu1); // \
1082    // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
1083  void test_method() EXCLUSIVE_LOCKS_REQUIRED(mu1);
1084};
1085
1086class 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() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.mu);
1094int elr_function_2() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu);
1095int elr_function_3() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.getMu());
1096int elr_function_4() EXCLUSIVE_LOCKS_REQUIRED(*muWrapper.getMuPointer());
1097int elr_function_5() EXCLUSIVE_LOCKS_REQUIRED(&mu1);
1098int elr_function_6() EXCLUSIVE_LOCKS_REQUIRED(muRef);
1099int elr_function_7() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu());
1100int elr_function_8() EXCLUSIVE_LOCKS_REQUIRED(muPointer);
1101
1102
1103// illegal attribute arguments
1104int elr_function_bad_1() 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() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \
1107  // expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}}
1108int elr_function_bad_3() 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() 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() SHARED_LOCKS_REQUIRED(mu1);
1130
1131void slr_function_args() SHARED_LOCKS_REQUIRED(mu1, mu2);
1132
1133int slr_testfn(int y) SHARED_LOCKS_REQUIRED(mu1);
1134
1135int slr_testfn(int y) {
1136  int x 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 SHARED_LOCKS_REQUIRED(mu1); // \
1142  // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
1143
1144void slr_fun_params(int lvar 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 SHARED_LOCKS_REQUIRED(mu1); // \
1150    // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
1151  void test_method() SHARED_LOCKS_REQUIRED(mu1);
1152};
1153
1154class 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() SHARED_LOCKS_REQUIRED(muWrapper.mu);
1162int slr_function_2() SHARED_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu);
1163int slr_function_3() SHARED_LOCKS_REQUIRED(muWrapper.getMu());
1164int slr_function_4() SHARED_LOCKS_REQUIRED(*muWrapper.getMuPointer());
1165int slr_function_5() SHARED_LOCKS_REQUIRED(&mu1);
1166int slr_function_6() SHARED_LOCKS_REQUIRED(muRef);
1167int slr_function_7() SHARED_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu());
1168int slr_function_8() SHARED_LOCKS_REQUIRED(muPointer);
1169
1170
1171// illegal attribute arguments
1172int slr_function_bad_1() 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() SHARED_LOCKS_REQUIRED("mu"); // \
1175  // expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}}
1176int slr_function_bad_3() 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() 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
1243Mutex gmu;
1244
1245class StaticMu {
1246  static Mutex statmu;
1247};
1248
1249class FooLate {
1250public:
1251  void foo1()           EXCLUSIVE_LOCKS_REQUIRED(gmu)   { }
1252  void foo2()           EXCLUSIVE_LOCKS_REQUIRED(mu)    { }
1253  void foo3(Mutex *m)   EXCLUSIVE_LOCKS_REQUIRED(m)     { }
1254  void foo3(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { }
1255  void foo4(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu);
1256
1257  static void foo5()    EXCLUSIVE_LOCKS_REQUIRED(mu); // \
1258    // expected-error {{invalid use of member 'mu' in static member function}}
1259
1260  template <class T>
1261  void foo6() EXCLUSIVE_LOCKS_REQUIRED(T::statmu) { }
1262
1263  template <class T>
1264  void foo7(T* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { }
1265
1266  int a GUARDED_BY(gmu);
1267  int b GUARDED_BY(mu);
1268  int c GUARDED_BY(this->mu);
1269
1270  Mutex mu;
1271};
1272
1273//-------------------------
1274// Empty argument lists
1275//-------------------------
1276
1277class LOCKABLE EmptyArgListsTest {
1278  void lock() EXCLUSIVE_LOCK_FUNCTION() { }
1279  void unlock() UNLOCK_FUNCTION() { }
1280};
1281
1282
1283namespace FunctionDefinitionParseTest {
1284// Test parsing of attributes on function definitions.
1285
1286class Foo {
1287public:
1288  Mutex mu_;
1289  void foo1();
1290  void foo2(Foo *f);
1291};
1292
1293template <class T>
1294class Bar {
1295public:
1296  Mutex mu_;
1297  void bar();
1298};
1299
1300void Foo::foo1()       EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
1301void Foo::foo2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { }
1302
1303template <class T>
1304void Bar<T>::bar() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
1305
1306void baz(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { }
1307
1308} // end namespace
1309
1310
1311namespace TestMultiDecl {
1312
1313class Foo {
1314public:
1315  int GUARDED_BY(mu_) a;
1316  int GUARDED_BY(mu_) b, c;
1317
1318private:
1319  Mutex mu_;
1320};
1321
1322} // end namespace TestMultiDecl
1323
1324
1325namespace NestedClassLateDecl {
1326
1327class Foo {
1328  class Bar {
1329    int a GUARDED_BY(mu);
1330    int b GUARDED_BY(fooMuStatic);
1331
1332    void bar()        EXCLUSIVE_LOCKS_REQUIRED(mu)       { a = 0;    }
1333    void bar2(Bar* b) EXCLUSIVE_LOCKS_REQUIRED(b->mu)    { b->a = 0; }
1334    void bar3(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->fooMu) { f->a = 0; }
1335
1336    Mutex mu;
1337  };
1338
1339  int a GUARDED_BY(fooMu);
1340  Mutex fooMu;
1341  static Mutex fooMuStatic;
1342};
1343
1344}
1345
1346namespace PointerToMemberTest {
1347
1348// Empty string should be ignored.
1349int  testEmptyAttribute GUARDED_BY("");
1350void testEmptyAttributeFunction() EXCLUSIVE_LOCKS_REQUIRED("");
1351
1352class Graph {
1353public:
1354  Mutex mu_;
1355
1356  static Mutex* get_static_mu() LOCK_RETURNED(&Graph::mu_);
1357};
1358
1359class Node {
1360public:
1361  void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_);
1362  int a GUARDED_BY(&Graph::mu_);
1363};
1364
1365}
1366
1367
1368namespace SmartPointerTest {
1369
1370template<class T>
1371class smart_ptr {
1372 public:
1373  T* operator->() { return ptr_; }
1374  T& operator*()  { return ptr_; }
1375
1376 private:
1377  T* ptr_;
1378};
1379
1380
1381Mutex gmu;
1382smart_ptr<int> gdat PT_GUARDED_BY(gmu);
1383
1384
1385class MyClass {
1386public:
1387  Mutex mu_;
1388  smart_ptr<Mutex> smu_;
1389
1390
1391  smart_ptr<int> a PT_GUARDED_BY(mu_);
1392  int b            GUARDED_BY(smu_);
1393};
1394
1395}
1396
1397
1398namespace InheritanceTest {
1399
1400class LOCKABLE Base {
1401 public:
1402  void lock()   EXCLUSIVE_LOCK_FUNCTION();
1403  void unlock() UNLOCK_FUNCTION();
1404};
1405
1406class Base2 { };
1407
1408class Derived1 : public Base { };
1409
1410class Derived2 : public Base2, public Derived1 { };
1411
1412class Derived3 : public Base2 { };
1413
1414class Foo {
1415  Derived1 mu1_;
1416  Derived2 mu2_;
1417  Derived3 mu3_;
1418  int a GUARDED_BY(mu1_);
1419  int b GUARDED_BY(mu2_);
1420  int c GUARDED_BY(mu3_);  // \
1421    // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class InheritanceTest::Derived3'}}
1422
1423  void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1_, mu2_) {
1424    a = 0;
1425    b = 0;
1426  }
1427};
1428
1429}
1430
1431
1432namespace InvalidDeclTest {
1433
1434class Foo { };
1435namespace {
1436void Foo::bar(Mutex* mu) LOCKS_EXCLUDED(mu) { } // \
1437   // expected-error   {{cannot define or redeclare 'bar' here because namespace '' does not enclose namespace 'Foo'}} \
1438   // expected-warning {{attribute locks_excluded ignored, because it is not attached to a declaration}}
1439}
1440
1441} // end namespace InvalidDeclTest
1442
1443
1444namespace StaticScopeTest {
1445
1446class FooStream;
1447
1448class Foo {
1449  mutable Mutex mu;
1450  int a GUARDED_BY(mu);
1451
1452  static int si GUARDED_BY(mu); // \
1453    // expected-error {{invalid use of non-static data member 'mu'}}
1454
1455  static void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \
1456    // expected-error {{invalid use of member 'mu' in static member function}}
1457
1458  friend FooStream& operator<<(FooStream& s, const Foo& f)
1459    EXCLUSIVE_LOCKS_REQUIRED(mu); // \
1460    // expected-error {{invalid use of non-static data member 'mu'}}
1461};
1462
1463
1464} // end namespace StaticScopeTest
1465
1466
1467namespace FunctionAttributesInsideClass_ICE_Test {
1468
1469class Foo {
1470public:
1471  /*  Originally found when parsing foo() as an ordinary method after the
1472   *  the following:
1473
1474  template <class T>
1475  void syntaxErrorMethod(int i) {
1476    if (i) {
1477      foo(
1478    }
1479  }
1480  */
1481
1482  void method() {
1483    void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \
1484      // expected-error {{use of undeclared identifier 'mu'}}
1485  }
1486};
1487
1488}  // end namespace FunctionAttributesInsideClass_ICE_Test
1489
1490