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