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