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 //  Helper fields
26 //-----------------------------------------//
27 
28 
29 class  __attribute__((lockable)) Mutex {
30  public:
31   void Lock() __attribute__((exclusive_lock_function));
32   void ReaderLock() __attribute__((shared_lock_function));
33   void Unlock() __attribute__((unlock_function));
34   bool TryLock() __attribute__((exclusive_trylock_function(true)));
35   bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
36   void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
37 };
38 
39 
40 Mutex sls_mu;
41 
42 Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
43 int sls_guard_var __attribute__((guarded_var)) = 0;
44 int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
45 
46 bool getBool();
47 
48 class MutexWrapper {
49 public:
50    Mutex mu;
51    int x __attribute__((guarded_by(mu)));
52    void MyLock() __attribute__((exclusive_lock_function(mu)));
53 };
54 
55 MutexWrapper sls_mw;
56 
57 void sls_fun_0() {
58   sls_mw.mu.Lock();
59   sls_mw.x = 5;
60   sls_mw.mu.Unlock();
61 }
62 
63 void sls_fun_2() {
64   sls_mu.Lock();
65   int x = sls_guard_var;
66   sls_mu.Unlock();
67 }
68 
69 void sls_fun_3() {
70   sls_mu.Lock();
71   sls_guard_var = 2;
72   sls_mu.Unlock();
73 }
74 
75 void sls_fun_4() {
76   sls_mu2.Lock();
77   sls_guard_var = 2;
78   sls_mu2.Unlock();
79 }
80 
81 void sls_fun_5() {
82   sls_mu.Lock();
83   int x = sls_guardby_var;
84   sls_mu.Unlock();
85 }
86 
87 void sls_fun_6() {
88   sls_mu.Lock();
89   sls_guardby_var = 2;
90   sls_mu.Unlock();
91 }
92 
93 void sls_fun_7() {
94   sls_mu.Lock();
95   sls_mu2.Lock();
96   sls_mu2.Unlock();
97   sls_mu.Unlock();
98 }
99 
100 void sls_fun_8() {
101   sls_mu.Lock();
102   if (getBool())
103     sls_mu.Unlock();
104   else
105     sls_mu.Unlock();
106 }
107 
108 void sls_fun_9() {
109   if (getBool())
110     sls_mu.Lock();
111   else
112     sls_mu.Lock();
113   sls_mu.Unlock();
114 }
115 
116 void sls_fun_good_6() {
117   if (getBool()) {
118     sls_mu.Lock();
119   } else {
120     if (getBool()) {
121       getBool(); // EMPTY
122     } else {
123       getBool(); // EMPTY
124     }
125     sls_mu.Lock();
126   }
127   sls_mu.Unlock();
128 }
129 
130 void sls_fun_good_7() {
131   sls_mu.Lock();
132   while (getBool()) {
133     sls_mu.Unlock();
134     if (getBool()) {
135       if (getBool()) {
136         sls_mu.Lock();
137         continue;
138       }
139     }
140     sls_mu.Lock();
141   }
142   sls_mu.Unlock();
143 }
144 
145 void sls_fun_good_8() {
146   sls_mw.MyLock();
147   sls_mw.mu.Unlock();
148 }
149 
150 void sls_fun_bad_1() {
151   sls_mu.Unlock(); // \
152     // expected-warning{{unlocking 'sls_mu' that was not locked}}
153 }
154 
155 void sls_fun_bad_2() {
156   sls_mu.Lock();
157   sls_mu.Lock(); // \
158     // expected-warning{{locking 'sls_mu' that is already locked}}
159   sls_mu.Unlock();
160 }
161 
162 void sls_fun_bad_3() {
163   sls_mu.Lock(); // \
164     // expected-warning{{mutex 'sls_mu' is still locked at the end of function 'sls_fun_bad_3'}}
165 }
166 
167 void sls_fun_bad_4() {
168   if (getBool())
169     sls_mu.Lock(); // \
170       // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}}
171   else
172     sls_mu2.Lock(); // \
173       // expected-warning{{mutex 'sls_mu2' is still locked at the end of its scope}}
174 }
175 
176 void sls_fun_bad_5() {
177   sls_mu.Lock(); // \
178     // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}}
179   if (getBool())
180     sls_mu.Unlock();
181 }
182 
183 void sls_fun_bad_6() {
184   if (getBool()) {
185     sls_mu.Lock(); // \
186       // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}}
187   } else {
188     if (getBool()) {
189       getBool(); // EMPTY
190     } else {
191       getBool(); // EMPTY
192     }
193   }
194   sls_mu.Unlock(); // \
195     // expected-warning{{unlocking 'sls_mu' that was not locked}}
196 }
197 
198 void sls_fun_bad_7() {
199   sls_mu.Lock(); // \
200     // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
201   while (getBool()) {
202     sls_mu.Unlock();
203     if (getBool()) {
204       if (getBool()) {
205         continue;
206       }
207     }
208     sls_mu.Lock(); // \
209       // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}}
210   }
211   sls_mu.Unlock();
212 }
213 
214 void sls_fun_bad_8() {
215   sls_mu.Lock(); // \
216     // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
217   do {
218     sls_mu.Unlock();
219   } while (getBool());
220 }
221 
222 void sls_fun_bad_9() {
223   do {
224     sls_mu.Lock(); // \
225       // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
226   } while (getBool());
227   sls_mu.Unlock();
228 }
229 
230 void sls_fun_bad_10() {
231   sls_mu.Lock(); // \
232     // expected-warning{{mutex 'sls_mu' is still locked at the end of function 'sls_fun_bad_10'}} \
233     // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
234   while(getBool()) {
235     sls_mu.Unlock();
236   }
237 }
238 
239 void sls_fun_bad_11() {
240   while (getBool()) {
241     sls_mu.Lock(); // \
242       // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
243   }
244   sls_mu.Unlock(); // \
245     // expected-warning{{unlocking 'sls_mu' that was not locked}}
246 }
247 
248 //-----------------------------------------//
249 // Handling lock expressions in attribute args
250 // -------------------------------------------//
251 
252 Mutex aa_mu;
253 
254 class GlobalLocker {
255 public:
256   void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
257   void globalUnlock() __attribute__((unlock_function(aa_mu)));
258 };
259 
260 GlobalLocker glock;
261 
262 void aa_fun_1() {
263   glock.globalLock();
264   glock.globalUnlock();
265 }
266 
267 void aa_fun_bad_1() {
268   glock.globalUnlock(); // \
269     // expected-warning{{unlocking 'aa_mu' that was not locked}}
270 }
271 
272 void aa_fun_bad_2() {
273   glock.globalLock();
274   glock.globalLock(); // \
275     // expected-warning{{locking 'aa_mu' that is already locked}}
276   glock.globalUnlock();
277 }
278 
279 void aa_fun_bad_3() {
280   glock.globalLock(); // \
281     // expected-warning{{mutex 'aa_mu' is still locked at the end of function 'aa_fun_bad_3'}}
282 }
283 
284 //--------------------------------------------------//
285 // Regression tests for unusual method names
286 //--------------------------------------------------//
287 
288 Mutex wmu;
289 
290 // Test diagnostics for other method names.
291 class WeirdMethods {
292   WeirdMethods() {
293     wmu.Lock(); // \
294       // expected-warning {{mutex 'wmu' is still locked at the end of function 'WeirdMethods'}}
295   }
296   ~WeirdMethods() {
297     wmu.Lock(); // \
298       // expected-warning {{mutex 'wmu' is still locked at the end of function '~WeirdMethods'}}
299   }
300   void operator++() {
301     wmu.Lock(); // \
302       // expected-warning {{mutex 'wmu' is still locked at the end of function 'operator++'}}
303   }
304   operator int*() {
305     wmu.Lock(); // \
306       // expected-warning {{mutex 'wmu' is still locked at the end of function 'operator int *'}}
307     return 0;
308   }
309 };
310 
311 //-----------------------------------------------//
312 // Errors for guarded by or guarded var variables
313 // ----------------------------------------------//
314 
315 int *pgb_gvar __attribute__((pt_guarded_var));
316 int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
317 
318 class PGBFoo {
319  public:
320   int x;
321   int *pgb_field __attribute__((guarded_by(sls_mu2)))
322                  __attribute__((pt_guarded_by(sls_mu)));
323   void testFoo() {
324     pgb_field = &x; // \
325       // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
326     *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
327       // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
328     x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
329       // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
330     (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
331       // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
332   }
333 };
334 
335 class GBFoo {
336  public:
337   int gb_field __attribute__((guarded_by(sls_mu)));
338 
339   void testFoo() {
340     gb_field = 0; // \
341       // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
342   }
343 
344   void testNoAnal() __attribute__((no_thread_safety_analysis)) {
345     gb_field = 0;
346   }
347 };
348 
349 GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
350 
351 void gb_fun_0() {
352   sls_mu.Lock();
353   int x = *pgb_var;
354   sls_mu.Unlock();
355 }
356 
357 void gb_fun_1() {
358   sls_mu.Lock();
359   *pgb_var = 2;
360   sls_mu.Unlock();
361 }
362 
363 void gb_fun_2() {
364   int x;
365   pgb_var = &x;
366 }
367 
368 void gb_fun_3() {
369   int *x = pgb_var;
370 }
371 
372 void gb_bad_0() {
373   sls_guard_var = 1; // \
374     // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
375 }
376 
377 void gb_bad_1() {
378   int x = sls_guard_var; // \
379     // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
380 }
381 
382 void gb_bad_2() {
383   sls_guardby_var = 1; // \
384     // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
385 }
386 
387 void gb_bad_3() {
388   int x = sls_guardby_var; // \
389     // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
390 }
391 
392 void gb_bad_4() {
393   *pgb_gvar = 1; // \
394     // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
395 }
396 
397 void gb_bad_5() {
398   int x = *pgb_gvar; // \
399     // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
400 }
401 
402 void gb_bad_6() {
403   *pgb_var = 1; // \
404     // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
405 }
406 
407 void gb_bad_7() {
408   int x = *pgb_var; // \
409     // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
410 }
411 
412 void gb_bad_8() {
413   GBFoo G;
414   G.gb_field = 0; // \
415     // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
416 }
417 
418 void gb_bad_9() {
419   sls_guard_var++; // \
420     // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
421   sls_guard_var--; // \
422     // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
423   ++sls_guard_var; // \
424     // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
425   --sls_guard_var;// \
426     // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
427 }
428 
429 //-----------------------------------------------//
430 // Warnings on variables with late parsed attributes
431 // ----------------------------------------------//
432 
433 class LateFoo {
434 public:
435   int a __attribute__((guarded_by(mu)));
436   int b;
437 
438   void foo() __attribute__((exclusive_locks_required(mu))) { }
439 
440   void test() {
441     a = 0; // \
442       // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
443     b = a; // \
444       // expected-warning {{reading variable 'a' requires locking 'mu'}}
445     c = 0; // \
446       // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
447   }
448 
449   int c __attribute__((guarded_by(mu)));
450 
451   Mutex mu;
452 };
453 
454 class LateBar {
455  public:
456   int a_ __attribute__((guarded_by(mu1_)));
457   int b_;
458   int *q __attribute__((pt_guarded_by(mu)));
459   Mutex mu1_;
460   Mutex mu;
461   LateFoo Foo;
462   LateFoo Foo2;
463   LateFoo *FooPointer;
464 };
465 
466 LateBar b1, *b3;
467 
468 void late_0() {
469   LateFoo FooA;
470   LateFoo FooB;
471   FooA.mu.Lock();
472   FooA.a = 5;
473   FooA.mu.Unlock();
474 }
475 
476 void late_1() {
477   LateBar BarA;
478   BarA.FooPointer->mu.Lock();
479   BarA.FooPointer->a = 2;
480   BarA.FooPointer->mu.Unlock();
481 }
482 
483 void late_bad_0() {
484   LateFoo fooA;
485   LateFoo fooB;
486   fooA.mu.Lock();
487   fooB.a = 5; // \
488     // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
489   fooA.mu.Unlock();
490 }
491 
492 void late_bad_1() {
493   Mutex mu;
494   mu.Lock();
495   b1.mu1_.Lock();
496   int res = b1.a_ + b3->b_;
497   b3->b_ = *b1.q; // \
498     // expected-warning{{reading the value pointed to by 'q' requires locking 'mu'}}
499   b1.mu1_.Unlock();
500   b1.b_ = res;
501   mu.Unlock();
502 }
503 
504 void late_bad_2() {
505   LateBar BarA;
506   BarA.FooPointer->mu.Lock();
507   BarA.Foo.a = 2; // \
508     // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
509   BarA.FooPointer->mu.Unlock();
510 }
511 
512 void late_bad_3() {
513   LateBar BarA;
514   BarA.Foo.mu.Lock();
515   BarA.FooPointer->a = 2; // \
516     // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
517   BarA.Foo.mu.Unlock();
518 }
519 
520 void late_bad_4() {
521   LateBar BarA;
522   BarA.Foo.mu.Lock();
523   BarA.Foo2.a = 2; // \
524     // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
525   BarA.Foo.mu.Unlock();
526 }
527 
528 //-----------------------------------------------//
529 // Extra warnings for shared vs. exclusive locks
530 // ----------------------------------------------//
531 
532 void shared_fun_0() {
533   sls_mu.Lock();
534   do {
535     sls_mu.Unlock();
536     sls_mu.Lock();
537   } while (getBool());
538   sls_mu.Unlock();
539 }
540 
541 void shared_fun_1() {
542   sls_mu.ReaderLock(); // \
543     // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
544   do {
545     sls_mu.Unlock();
546     sls_mu.Lock();  // \
547       // expected-note {{the other lock of mutex 'sls_mu' is here}}
548   } while (getBool());
549   sls_mu.Unlock();
550 }
551 
552 void shared_fun_3() {
553   if (getBool())
554     sls_mu.Lock();
555   else
556     sls_mu.Lock();
557   *pgb_var = 1;
558   sls_mu.Unlock();
559 }
560 
561 void shared_fun_4() {
562   if (getBool())
563     sls_mu.ReaderLock();
564   else
565     sls_mu.ReaderLock();
566   int x = sls_guardby_var;
567   sls_mu.Unlock();
568 }
569 
570 void shared_fun_8() {
571   if (getBool())
572     sls_mu.Lock(); // \
573       // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
574   else
575     sls_mu.ReaderLock(); // \
576       // expected-note {{the other lock of mutex 'sls_mu' is here}}
577   sls_mu.Unlock();
578 }
579 
580 void shared_bad_0() {
581   sls_mu.Lock();  // \
582     // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
583   do {
584     sls_mu.Unlock();
585     sls_mu.ReaderLock();  // \
586       // expected-note {{the other lock of mutex 'sls_mu' is here}}
587   } while (getBool());
588   sls_mu.Unlock();
589 }
590 
591 void shared_bad_1() {
592   if (getBool())
593     sls_mu.Lock(); // \
594       // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
595   else
596     sls_mu.ReaderLock(); // \
597       // expected-note {{the other lock of mutex 'sls_mu' is here}}
598   *pgb_var = 1;
599   sls_mu.Unlock();
600 }
601 
602 void shared_bad_2() {
603   if (getBool())
604     sls_mu.ReaderLock(); // \
605       // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
606   else
607     sls_mu.Lock(); // \
608       // expected-note {{the other lock of mutex 'sls_mu' is here}}
609   *pgb_var = 1;
610   sls_mu.Unlock();
611 }
612 
613 // FIXME: Add support for functions (not only methods)
614 class LRBar {
615  public:
616   void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
617   void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
618   void le_fun() __attribute__((locks_excluded(sls_mu)));
619 };
620 
621 class LRFoo {
622  public:
623   void test() __attribute__((exclusive_locks_required(sls_mu)));
624   void testShared() __attribute__((shared_locks_required(sls_mu2)));
625 };
626 
627 void elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
628 void elr_fun() {}
629 
630 LRFoo MyLRFoo;
631 LRBar Bar;
632 
633 void es_fun_0() {
634   aa_mu.Lock();
635   Bar.aa_elr_fun();
636   aa_mu.Unlock();
637 }
638 
639 void es_fun_1() {
640   aa_mu.Lock();
641   Bar.aa_elr_fun_s();
642   aa_mu.Unlock();
643 }
644 
645 void es_fun_2() {
646   aa_mu.ReaderLock();
647   Bar.aa_elr_fun_s();
648   aa_mu.Unlock();
649 }
650 
651 void es_fun_3() {
652   sls_mu.Lock();
653   MyLRFoo.test();
654   sls_mu.Unlock();
655 }
656 
657 void es_fun_4() {
658   sls_mu2.Lock();
659   MyLRFoo.testShared();
660   sls_mu2.Unlock();
661 }
662 
663 void es_fun_5() {
664   sls_mu2.ReaderLock();
665   MyLRFoo.testShared();
666   sls_mu2.Unlock();
667 }
668 
669 void es_fun_6() {
670   Bar.le_fun();
671 }
672 
673 void es_fun_7() {
674   sls_mu.Lock();
675   elr_fun();
676   sls_mu.Unlock();
677 }
678 
679 void es_fun_8() __attribute__((no_thread_safety_analysis));
680 
681 void es_fun_8() {
682   Bar.aa_elr_fun_s();
683 }
684 
685 void es_fun_9() __attribute__((shared_locks_required(aa_mu)));
686 void es_fun_9() {
687   Bar.aa_elr_fun_s();
688 }
689 
690 void es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
691 void es_fun_10() {
692   Bar.aa_elr_fun_s();
693 }
694 
695 void es_bad_0() {
696   Bar.aa_elr_fun(); // \
697     // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
698 }
699 
700 void es_bad_1() {
701   aa_mu.ReaderLock();
702   Bar.aa_elr_fun(); // \
703     // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
704   aa_mu.Unlock();
705 }
706 
707 void es_bad_2() {
708   Bar.aa_elr_fun_s(); // \
709     // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
710 }
711 
712 void es_bad_3() {
713   MyLRFoo.test(); // \
714     // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
715 }
716 
717 void es_bad_4() {
718   MyLRFoo.testShared(); // \
719     // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
720 }
721 
722 void es_bad_5() {
723   sls_mu.ReaderLock();
724   MyLRFoo.test(); // \
725     // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
726   sls_mu.Unlock();
727 }
728 
729 void es_bad_6() {
730   sls_mu.Lock();
731   Bar.le_fun(); // \
732     // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
733   sls_mu.Unlock();
734 }
735 
736 void es_bad_7() {
737   sls_mu.ReaderLock();
738   Bar.le_fun(); // \
739     // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
740   sls_mu.Unlock();
741 }
742 
743 
744 //-----------------------------------------------//
745 // Unparseable lock expressions
746 // ----------------------------------------------//
747 
748 Mutex UPmu;
749 // FIXME: add support for lock expressions involving arrays.
750 Mutex mua[5];
751 
752 int x __attribute__((guarded_by(UPmu = sls_mu)));
753 int y __attribute__((guarded_by(mua[0])));
754 
755 
756 void testUnparse() {
757   x = 5; // \
758     // expected-warning{{cannot resolve lock expression}}
759   y = 5; // \
760     // expected-warning{{cannot resolve lock expression}}
761 }
762 
763 void testUnparse2() {
764   mua[0].Lock(); // \
765     // expected-warning{{cannot resolve lock expression}}
766   (&(mua[0]) + 4)->Lock(); // \
767     // expected-warning{{cannot resolve lock expression}}
768 }
769 
770 
771 //----------------------------------------------------------------------------//
772 // The following test cases are ported from the gcc thread safety implementation
773 // They are each wrapped inside a namespace with the test number of the gcc test
774 //
775 // FIXME: add all the gcc tests, once this analysis passes them.
776 //----------------------------------------------------------------------------//
777 
778 //-----------------------------------------//
779 // Good testcases (no errors)
780 //-----------------------------------------//
781 
782 namespace thread_annot_lock_20 {
783 class Bar {
784  public:
785   static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
786   static int b_ GUARDED_BY(mu1_);
787   static Mutex mu1_;
788   static int a_ GUARDED_BY(mu1_);
789 };
790 
791 Bar b1;
792 
793 int Bar::func1()
794 {
795   int res = 5;
796 
797   if (a_ == 4)
798     res = b_;
799   return res;
800 }
801 } // end namespace thread_annot_lock_20
802 
803 namespace thread_annot_lock_22 {
804 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
805 // uses in class definitions.
806 Mutex mu;
807 
808 class Bar {
809  public:
810   int a_ GUARDED_BY(mu1_);
811   int b_;
812   int *q PT_GUARDED_BY(mu);
813   Mutex mu1_ ACQUIRED_AFTER(mu);
814 };
815 
816 Bar b1, *b3;
817 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
818 int res GUARDED_BY(mu) = 5;
819 
820 int func(int i)
821 {
822   int x;
823   mu.Lock();
824   b1.mu1_.Lock();
825   res = b1.a_ + b3->b_;
826   *p = i;
827   b1.a_ = res + b3->b_;
828   b3->b_ = *b1.q;
829   b1.mu1_.Unlock();
830   b1.b_ = res;
831   x = res;
832   mu.Unlock();
833   return x;
834 }
835 } // end namespace thread_annot_lock_22
836 
837 namespace thread_annot_lock_27_modified {
838 // test lock annotations applied to function definitions
839 // Modified: applied annotations only to function declarations
840 Mutex mu1;
841 Mutex mu2 ACQUIRED_AFTER(mu1);
842 
843 class Foo {
844  public:
845   int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
846 };
847 
848 int Foo::method1(int i) {
849   return i;
850 }
851 
852 
853 int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
854 int foo(int i) {
855   return i;
856 }
857 
858 static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
859 static int bar(int i) {
860   return i;
861 }
862 
863 void main() {
864   Foo a;
865 
866   mu1.Lock();
867   mu2.Lock();
868   a.method1(1);
869   foo(2);
870   mu2.Unlock();
871   bar(3);
872   mu1.Unlock();
873 }
874 } // end namespace thread_annot_lock_27_modified
875 
876 
877 namespace thread_annot_lock_38 {
878 // Test the case where a template member function is annotated with lock
879 // attributes in a non-template class.
880 class Foo {
881  public:
882   void func1(int y) LOCKS_EXCLUDED(mu_);
883   template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
884  private:
885   Mutex mu_;
886 };
887 
888 Foo *foo;
889 
890 void main()
891 {
892   foo->func1(5);
893   foo->func2(5);
894 }
895 } // end namespace thread_annot_lock_38
896 
897 namespace thread_annot_lock_43 {
898 // Tests lock canonicalization
899 class Foo {
900  public:
901   Mutex *mu_;
902 };
903 
904 class FooBar {
905  public:
906   Foo *foo_;
907   int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
908   int a_ GUARDED_BY(foo_->mu_);
909 };
910 
911 FooBar *fb;
912 
913 void main()
914 {
915   int x;
916   fb->foo_->mu_->Lock();
917   x = fb->GetA();
918   fb->foo_->mu_->Unlock();
919 }
920 } // end namespace thread_annot_lock_43
921 
922 namespace thread_annot_lock_49 {
923 // Test the support for use of lock expression in the annotations
924 class Foo {
925  public:
926   Mutex foo_mu_;
927 };
928 
929 class Bar {
930  private:
931   Foo *foo;
932   Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
933 
934  public:
935   void Test1() {
936     foo->foo_mu_.Lock();
937     bar_mu_.Lock();
938     bar_mu_.Unlock();
939     foo->foo_mu_.Unlock();
940   }
941 };
942 
943 void main() {
944   Bar bar;
945   bar.Test1();
946 }
947 } // end namespace thread_annot_lock_49
948 
949 namespace thread_annot_lock_61_modified {
950   // Modified to fix the compiler errors
951   // Test the fix for a bug introduced by the support of pass-by-reference
952   // paramters.
953   struct Foo { Foo &operator<< (bool) {return *this;} };
954   Foo &getFoo();
955   struct Bar { Foo &func () {return getFoo();} };
956   struct Bas { void operator& (Foo &) {} };
957   void mumble()
958   {
959     Bas() & Bar().func() << "" << "";
960     Bas() & Bar().func() << "";
961   }
962 } // end namespace thread_annot_lock_61_modified
963 
964 
965 namespace thread_annot_lock_65 {
966 // Test the fix for a bug in the support of allowing reader locks for
967 // non-const, non-modifying overload functions. (We didn't handle the builtin
968 // properly.)
969 enum MyFlags {
970   Zero,
971   One,
972   Two,
973   Three,
974   Four,
975   Five,
976   Six,
977   Seven,
978   Eight,
979   Nine
980 };
981 
982 inline MyFlags
983 operator|(MyFlags a, MyFlags b)
984 {
985   return MyFlags(static_cast<int>(a) | static_cast<int>(b));
986 }
987 
988 inline MyFlags&
989 operator|=(MyFlags& a, MyFlags b)
990 {
991     return a = a | b;
992 }
993 } // end namespace thread_annot_lock_65
994 
995 namespace thread_annot_lock_66_modified {
996 // Modified: Moved annotation to function defn
997 // Test annotations on out-of-line definitions of member functions where the
998 // annotations refer to locks that are also data members in the class.
999 Mutex mu;
1000 
1001 class Foo {
1002  public:
1003   int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1004   int data GUARDED_BY(mu1);
1005   Mutex *mu1;
1006   Mutex *mu2;
1007 };
1008 
1009 int Foo::method1(int i)
1010 {
1011   return data + i;
1012 }
1013 
1014 void main()
1015 {
1016   Foo a;
1017 
1018   a.mu2->Lock();
1019   a.mu1->Lock();
1020   mu.Lock();
1021   a.method1(1);
1022   mu.Unlock();
1023   a.mu1->Unlock();
1024   a.mu2->Unlock();
1025 }
1026 } // end namespace thread_annot_lock_66_modified
1027 
1028 namespace thread_annot_lock_68_modified {
1029 // Test a fix to a bug in the delayed name binding with nested template
1030 // instantiation. We use a stack to make sure a name is not resolved to an
1031 // inner context.
1032 template <typename T>
1033 class Bar {
1034   Mutex mu_;
1035 };
1036 
1037 template <typename T>
1038 class Foo {
1039  public:
1040   void func(T x) {
1041     mu_.Lock();
1042     count_ = x;
1043     mu_.Unlock();
1044   }
1045 
1046  private:
1047   T count_ GUARDED_BY(mu_);
1048   Bar<T> bar_;
1049   Mutex mu_;
1050 };
1051 
1052 void main()
1053 {
1054   Foo<int> *foo;
1055   foo->func(5);
1056 }
1057 } // end namespace thread_annot_lock_68_modified
1058 
1059 namespace thread_annot_lock_30_modified {
1060 // Test delay parsing of lock attribute arguments with nested classes.
1061 // Modified: trylocks replaced with exclusive_lock_fun
1062 int a = 0;
1063 
1064 class Bar {
1065   struct Foo;
1066 
1067  public:
1068   void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1069 
1070   int func() {
1071     MyLock();
1072 //    if (foo == 0) {
1073 //      return 0;
1074 //    }
1075     a = 5;
1076     mu.Unlock();
1077     return 1;
1078   }
1079 
1080   class FooBar {
1081     int x;
1082     int y;
1083   };
1084 
1085  private:
1086   Mutex mu;
1087 };
1088 
1089 Bar *bar;
1090 
1091 void main()
1092 {
1093   bar->func();
1094 }
1095 } // end namespace thread_annot_lock_30_modified
1096 
1097 namespace thread_annot_lock_47 {
1098 // Test the support for annotations on virtual functions.
1099 // This is a good test case. (i.e. There should be no warning emitted by the
1100 // compiler.)
1101 class Base {
1102  public:
1103   virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1104   virtual void func2() LOCKS_EXCLUDED(mu_);
1105   Mutex mu_;
1106 };
1107 
1108 class Child : public Base {
1109  public:
1110   virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1111   virtual void func2() LOCKS_EXCLUDED(mu_);
1112 };
1113 
1114 void main() {
1115   Child *c;
1116   Base *b = c;
1117 
1118   b->mu_.Lock();
1119   b->func1();
1120   b->mu_.Unlock();
1121   b->func2();
1122 
1123   c->mu_.Lock();
1124   c->func1();
1125   c->mu_.Unlock();
1126   c->func2();
1127 }
1128 } // end namespace thread_annot_lock_47
1129 
1130 //-----------------------------------------//
1131 // Tests which produce errors
1132 //-----------------------------------------//
1133 
1134 namespace thread_annot_lock_13 {
1135 Mutex mu1;
1136 Mutex mu2;
1137 
1138 int g GUARDED_BY(mu1);
1139 int w GUARDED_BY(mu2);
1140 
1141 class Foo {
1142  public:
1143   void bar() LOCKS_EXCLUDED(mu_, mu1);
1144   int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1145 
1146  private:
1147   int a_ GUARDED_BY(mu_);
1148  public:
1149   Mutex mu_ ACQUIRED_AFTER(mu1);
1150 };
1151 
1152 int Foo::foo()
1153 {
1154   int res;
1155   w = 5.2;
1156   res = a_ + 5;
1157   return res;
1158 }
1159 
1160 void Foo::bar()
1161 {
1162   int x;
1163   mu_.Lock();
1164   x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
1165   a_ = x + 1;
1166   mu_.Unlock();
1167   if (x > 5) {
1168     mu1.Lock();
1169     g = 2.3;
1170     mu1.Unlock();
1171   }
1172 }
1173 
1174 void main()
1175 {
1176   Foo f1, *f2;
1177   f1.mu_.Lock();
1178   f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
1179   mu2.Lock();
1180   f1.foo();
1181   mu2.Unlock();
1182   f1.mu_.Unlock();
1183   f2->mu_.Lock();
1184   f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
1185   f2->mu_.Unlock();
1186   mu2.Lock();
1187   w = 2.5;
1188   mu2.Unlock();
1189 }
1190 } // end namespace thread_annot_lock_13
1191 
1192 namespace thread_annot_lock_18_modified {
1193 // Modified: Trylocks removed
1194 // Test the ability to distnguish between the same lock field of
1195 // different objects of a class.
1196   class Bar {
1197  public:
1198   bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1199   void MyUnlock() UNLOCK_FUNCTION(mu1_);
1200   int a_ GUARDED_BY(mu1_);
1201 
1202  private:
1203   Mutex mu1_;
1204 };
1205 
1206 Bar *b1, *b2;
1207 
1208 void func()
1209 {
1210   b1->MyLock();
1211   b1->a_ = 5;
1212   b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
1213   b2->MyLock();
1214   b2->MyUnlock();
1215   b1->MyUnlock();
1216 }
1217 } // end namespace thread_annot_lock_18_modified
1218 
1219 namespace thread_annot_lock_21 {
1220 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1221 // uses in class definitions.
1222 Mutex mu;
1223 
1224 class Bar {
1225  public:
1226   int a_ GUARDED_BY(mu1_);
1227   int b_;
1228   int *q PT_GUARDED_BY(mu);
1229   Mutex mu1_ ACQUIRED_AFTER(mu);
1230 };
1231 
1232 Bar b1, *b3;
1233 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1234 
1235 int res GUARDED_BY(mu) = 5;
1236 
1237 int func(int i)
1238 {
1239   int x;
1240   b3->mu1_.Lock();
1241   res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'mu1_'}} \
1242     // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}}
1243   *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
1244     // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
1245   b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
1246     // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
1247   b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
1248   b3->mu1_.Unlock();
1249   b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1250   x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1251   return x;
1252 }
1253 } // end namespace thread_annot_lock_21
1254 
1255 namespace thread_annot_lock_35_modified {
1256 // Test the analyzer's ability to distinguish the lock field of different
1257 // objects.
1258 class Foo {
1259  private:
1260   Mutex lock_;
1261   int a_ GUARDED_BY(lock_);
1262 
1263  public:
1264   void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1265      Foo *new_foo = new Foo;
1266 
1267      lock_.Lock();
1268 
1269      child->Func(new_foo); // There shouldn't be any warning here as the
1270                            // acquired lock is not in child.
1271      child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'lock_'}}
1272      child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'lock_' exclusively}}
1273      lock_.Unlock();
1274   }
1275 
1276   void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1277     a_ = y;
1278   }
1279 };
1280 
1281 Foo *x;
1282 
1283 void main() {
1284   Foo *child = new Foo;
1285   x->Func(child);
1286 }
1287 } // end namespace thread_annot_lock_35_modified
1288 
1289 namespace thread_annot_lock_36_modified {
1290 // Modified to move the annotations to function defns.
1291 // Test the analyzer's ability to distinguish the lock field of different
1292 // objects
1293 class Foo {
1294  private:
1295   Mutex lock_;
1296   int a_ GUARDED_BY(lock_);
1297 
1298  public:
1299   void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1300   void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1301 };
1302 
1303 void Foo::Func(Foo* child) {
1304   Foo *new_foo = new Foo;
1305 
1306   lock_.Lock();
1307 
1308   child->lock_.Lock();
1309   child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'lock_' is locked}}
1310   child->bar(7);
1311   child->a_ = 5;
1312   child->lock_.Unlock();
1313 
1314   lock_.Unlock();
1315 }
1316 
1317 void Foo::bar(int y) {
1318   a_ = y;
1319 }
1320 
1321 
1322 Foo *x;
1323 
1324 void main() {
1325   Foo *child = new Foo;
1326   x->Func(child);
1327 }
1328 } // end namespace thread_annot_lock_36_modified
1329 
1330 
1331 namespace thread_annot_lock_42 {
1332 // Test support of multiple lock attributes of the same kind on a decl.
1333 class Foo {
1334  private:
1335   Mutex mu1, mu2, mu3;
1336   int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1337   int y GUARDED_BY(mu2);
1338 
1339   void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1340     mu2.Lock();
1341     y = 2;
1342     mu2.Unlock();
1343   }
1344 
1345  public:
1346   void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1347     x = 5;
1348     f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
1349       // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
1350   }
1351 };
1352 
1353 Foo *foo;
1354 
1355 void func()
1356 {
1357   foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'mu2'}} \
1358     // expected-warning {{calling function 'f1' requires exclusive lock on 'mu1'}}
1359 }
1360 } // end namespace thread_annot_lock_42
1361 
1362 namespace thread_annot_lock_46 {
1363 // Test the support for annotations on virtual functions.
1364 class Base {
1365  public:
1366   virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1367   virtual void func2() LOCKS_EXCLUDED(mu_);
1368   Mutex mu_;
1369 };
1370 
1371 class Child : public Base {
1372  public:
1373   virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1374   virtual void func2() LOCKS_EXCLUDED(mu_);
1375 };
1376 
1377 void main() {
1378   Child *c;
1379   Base *b = c;
1380 
1381   b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
1382   b->mu_.Lock();
1383   b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
1384   b->mu_.Unlock();
1385 
1386   c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
1387   c->mu_.Lock();
1388   c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
1389   c->mu_.Unlock();
1390 }
1391 } // end namespace thread_annot_lock_46
1392 
1393 namespace thread_annot_lock_67_modified {
1394 // Modified: attributes on definitions moved to declarations
1395 // Test annotations on out-of-line definitions of member functions where the
1396 // annotations refer to locks that are also data members in the class.
1397 Mutex mu;
1398 Mutex mu3;
1399 
1400 class Foo {
1401  public:
1402   int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1403   int data GUARDED_BY(mu1);
1404   Mutex *mu1;
1405   Mutex *mu2;
1406 };
1407 
1408 int Foo::method1(int i) {
1409   return data + i;
1410 }
1411 
1412 void main()
1413 {
1414   Foo a;
1415   a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'mu1'}} \
1416     // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
1417     // expected-warning {{calling function 'method1' requires shared lock on 'mu2'}} \
1418     // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
1419 }
1420 } // end namespace thread_annot_lock_67_modified
1421 
1422 
1423 namespace substitution_test {
1424   class MyData  {
1425   public:
1426     Mutex mu;
1427 
1428     void lockData()    __attribute__((exclusive_lock_function(mu)))   { }
1429     void unlockData()  __attribute__((unlock_function(mu)))           { }
1430 
1431     void doSomething() __attribute__((exclusive_locks_required(mu)))  { }
1432   };
1433 
1434 
1435   class DataLocker {
1436   public:
1437     void lockData  (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { }
1438     void unlockData(MyData *d) __attribute__((unlock_function(d->mu)))         { }
1439   };
1440 
1441 
1442   class Foo {
1443   public:
1444     void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
1445 
1446     void bar1(MyData* d) {
1447       d->lockData();
1448       foo(d);
1449       d->unlockData();
1450     }
1451 
1452     void bar2(MyData* d) {
1453       DataLocker dlr;
1454       dlr.lockData(d);
1455       foo(d);
1456       dlr.unlockData(d);
1457     }
1458 
1459     void bar3(MyData* d1, MyData* d2) {
1460       DataLocker dlr;
1461       dlr.lockData(d1);   // \
1462         // expected-warning {{mutex 'mu' is still locked at the end of function}}
1463       dlr.unlockData(d2); // \
1464         // expected-warning {{unlocking 'mu' that was not locked}}
1465     }
1466 
1467     void bar4(MyData* d1, MyData* d2) {
1468       DataLocker dlr;
1469       dlr.lockData(d1);
1470       foo(d2); // \
1471         // expected-warning {{calling function 'foo' requires exclusive lock on 'mu'}}
1472       dlr.unlockData(d1);
1473     }
1474   };
1475 } // end namespace substituation_test
1476 
1477 
1478 
1479 namespace constructor_destructor_tests {
1480   Mutex fooMu;
1481   int myVar GUARDED_BY(fooMu);
1482 
1483   class Foo {
1484   public:
1485     Foo()  __attribute__((exclusive_lock_function(fooMu))) { }
1486     ~Foo() __attribute__((unlock_function(fooMu))) { }
1487   };
1488 
1489   void fooTest() {
1490     Foo foo;
1491     myVar = 0;
1492   }
1493 }
1494 
1495 
1496 namespace invalid_lock_expression_test {
1497 
1498 class LOCKABLE MyLockable {
1499 public:
1500   MyLockable() __attribute__((exclusive_lock_function)) { }
1501   ~MyLockable() { }
1502 };
1503 
1504 // create an empty lock expression
1505 void foo() {
1506   MyLockable lock;  // \
1507     // expected-warning {{cannot resolve lock expression}}
1508 }
1509 
1510 } // end namespace invalid_lock_expression_test
1511 
1512 namespace template_member_test {
1513 
1514   struct S { int n; };
1515   struct T {
1516     Mutex m;
1517     S *s GUARDED_BY(this->m);
1518   };
1519   Mutex m;
1520   struct U {
1521     union {
1522       int n;
1523     };
1524   } *u GUARDED_BY(m);
1525 
1526   template<typename U>
1527   struct IndirectLock {
1528     int DoNaughtyThings(T *t) {
1529       u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
1530       return t->s->n; // expected-warning {{reading variable 's' requires locking 'm'}}
1531     }
1532   };
1533 
1534   template struct IndirectLock<int>; // expected-note {{here}}
1535 
1536   struct V {
1537     void f(int);
1538     void f(double);
1539 
1540     Mutex m;
1541     V *p GUARDED_BY(this->m);
1542   };
1543   template<typename U> struct W {
1544     V v;
1545     void f(U u) {
1546       v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'm'}}
1547     }
1548   };
1549   template struct W<int>; // expected-note {{here}}
1550 
1551 }
1552