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