Clang Project

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