Home | History | Annotate | Download | only in SemaCXX
      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 class __attribute__((scoped_lockable)) MutexLock {
     40  public:
     41   MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
     42   ~MutexLock() __attribute__((unlock_function));
     43 };
     44 
     45 class __attribute__((scoped_lockable)) ReaderMutexLock {
     46  public:
     47   ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
     48   ~ReaderMutexLock() __attribute__((unlock_function));
     49 };
     50 
     51 
     52 Mutex sls_mu;
     53 
     54 Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
     55 int sls_guard_var __attribute__((guarded_var)) = 0;
     56 int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
     57 
     58 bool getBool();
     59 
     60 class MutexWrapper {
     61 public:
     62    Mutex mu;
     63    int x __attribute__((guarded_by(mu)));
     64    void MyLock() __attribute__((exclusive_lock_function(mu)));
     65 };
     66 
     67 MutexWrapper sls_mw;
     68 
     69 void sls_fun_0() {
     70   sls_mw.mu.Lock();
     71   sls_mw.x = 5;
     72   sls_mw.mu.Unlock();
     73 }
     74 
     75 void sls_fun_2() {
     76   sls_mu.Lock();
     77   int x = sls_guard_var;
     78   sls_mu.Unlock();
     79 }
     80 
     81 void sls_fun_3() {
     82   sls_mu.Lock();
     83   sls_guard_var = 2;
     84   sls_mu.Unlock();
     85 }
     86 
     87 void sls_fun_4() {
     88   sls_mu2.Lock();
     89   sls_guard_var = 2;
     90   sls_mu2.Unlock();
     91 }
     92 
     93 void sls_fun_5() {
     94   sls_mu.Lock();
     95   int x = sls_guardby_var;
     96   sls_mu.Unlock();
     97 }
     98 
     99 void sls_fun_6() {
    100   sls_mu.Lock();
    101   sls_guardby_var = 2;
    102   sls_mu.Unlock();
    103 }
    104 
    105 void sls_fun_7() {
    106   sls_mu.Lock();
    107   sls_mu2.Lock();
    108   sls_mu2.Unlock();
    109   sls_mu.Unlock();
    110 }
    111 
    112 void sls_fun_8() {
    113   sls_mu.Lock();
    114   if (getBool())
    115     sls_mu.Unlock();
    116   else
    117     sls_mu.Unlock();
    118 }
    119 
    120 void sls_fun_9() {
    121   if (getBool())
    122     sls_mu.Lock();
    123   else
    124     sls_mu.Lock();
    125   sls_mu.Unlock();
    126 }
    127 
    128 void sls_fun_good_6() {
    129   if (getBool()) {
    130     sls_mu.Lock();
    131   } else {
    132     if (getBool()) {
    133       getBool(); // EMPTY
    134     } else {
    135       getBool(); // EMPTY
    136     }
    137     sls_mu.Lock();
    138   }
    139   sls_mu.Unlock();
    140 }
    141 
    142 void sls_fun_good_7() {
    143   sls_mu.Lock();
    144   while (getBool()) {
    145     sls_mu.Unlock();
    146     if (getBool()) {
    147       if (getBool()) {
    148         sls_mu.Lock();
    149         continue;
    150       }
    151     }
    152     sls_mu.Lock();
    153   }
    154   sls_mu.Unlock();
    155 }
    156 
    157 void sls_fun_good_8() {
    158   sls_mw.MyLock();
    159   sls_mw.mu.Unlock();
    160 }
    161 
    162 void sls_fun_bad_1() {
    163   sls_mu.Unlock(); // \
    164     // expected-warning{{unlocking 'sls_mu' that was not locked}}
    165 }
    166 
    167 void sls_fun_bad_2() {
    168   sls_mu.Lock();
    169   sls_mu.Lock(); // \
    170     // expected-warning{{locking 'sls_mu' that is already locked}}
    171   sls_mu.Unlock();
    172 }
    173 
    174 void sls_fun_bad_3() {
    175   sls_mu.Lock(); // expected-note {{mutex acquired here}}
    176 } // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
    177 
    178 void sls_fun_bad_4() {
    179   if (getBool())
    180     sls_mu.Lock(); // \
    181   expected-warning{{mutex 'sls_mu2' is not locked on every path through here}} \
    182   expected-note{{mutex acquired here}}
    183 
    184   else
    185     sls_mu2.Lock(); // \
    186   expected-note{{mutex acquired here}}
    187 } // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
    188 
    189 void sls_fun_bad_5() {
    190   sls_mu.Lock(); // expected-note {{mutex acquired here}}
    191   if (getBool())
    192     sls_mu.Unlock();
    193 } // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
    194 
    195 void sls_fun_bad_6() {
    196   if (getBool()) {
    197     sls_mu.Lock(); // expected-note {{mutex acquired here}}
    198   } else {
    199     if (getBool()) {
    200       getBool(); // EMPTY
    201     } else {
    202       getBool(); // EMPTY
    203     }
    204   }
    205   sls_mu.Unlock(); // \
    206     expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
    207     expected-warning{{unlocking 'sls_mu' that was not locked}}
    208 }
    209 
    210 void sls_fun_bad_7() {
    211   sls_mu.Lock();
    212   while (getBool()) {
    213     sls_mu.Unlock();
    214     if (getBool()) {
    215       if (getBool()) {
    216         continue; // \
    217         expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
    218       }
    219     }
    220     sls_mu.Lock(); // expected-note {{mutex acquired here}}
    221   }
    222   sls_mu.Unlock();
    223 }
    224 
    225 void sls_fun_bad_8() {
    226   sls_mu.Lock(); // expected-note{{mutex acquired here}}
    227 
    228   // FIXME: TERRIBLE SOURCE LOCATION!
    229   do { // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
    230     sls_mu.Unlock();
    231   } while (getBool());
    232 }
    233 
    234 void sls_fun_bad_9() {
    235   do {
    236     sls_mu.Lock(); // \
    237       // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
    238       // expected-note{{mutex acquired here}}
    239   } while (getBool());
    240   sls_mu.Unlock();
    241 }
    242 
    243 void sls_fun_bad_10() {
    244   sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
    245   while(getBool()) {
    246     sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
    247   }
    248 } // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
    249 
    250 void sls_fun_bad_11() {
    251   while (getBool()) { // \
    252    expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
    253     sls_mu.Lock(); // expected-note {{mutex acquired here}}
    254   }
    255   sls_mu.Unlock(); // \
    256     // expected-warning{{unlocking 'sls_mu' that was not locked}}
    257 }
    258 
    259 void sls_fun_bad_12() {
    260   sls_mu.Lock(); // expected-note {{mutex acquired here}}
    261   while (getBool()) {
    262     sls_mu.Unlock();
    263     if (getBool()) {
    264       if (getBool()) {
    265         break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
    266       }
    267     }
    268     sls_mu.Lock();
    269   }
    270   sls_mu.Unlock();
    271 }
    272 
    273 //-----------------------------------------//
    274 // Handling lock expressions in attribute args
    275 // -------------------------------------------//
    276 
    277 Mutex aa_mu;
    278 
    279 class GlobalLocker {
    280 public:
    281   void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
    282   void globalUnlock() __attribute__((unlock_function(aa_mu)));
    283 };
    284 
    285 GlobalLocker glock;
    286 
    287 void aa_fun_1() {
    288   glock.globalLock();
    289   glock.globalUnlock();
    290 }
    291 
    292 void aa_fun_bad_1() {
    293   glock.globalUnlock(); // \
    294     // expected-warning{{unlocking 'aa_mu' that was not locked}}
    295 }
    296 
    297 void aa_fun_bad_2() {
    298   glock.globalLock();
    299   glock.globalLock(); // \
    300     // expected-warning{{locking 'aa_mu' that is already locked}}
    301   glock.globalUnlock();
    302 }
    303 
    304 void aa_fun_bad_3() {
    305   glock.globalLock(); // expected-note{{mutex acquired here}}
    306 } // expected-warning{{mutex 'aa_mu' is still locked at the end of function}}
    307 
    308 //--------------------------------------------------//
    309 // Regression tests for unusual method names
    310 //--------------------------------------------------//
    311 
    312 Mutex wmu;
    313 
    314 // Test diagnostics for other method names.
    315 class WeirdMethods {
    316   // FIXME: can't currently check inside constructors and destructors.
    317   WeirdMethods() {
    318     wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
    319   } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
    320   ~WeirdMethods() {
    321     wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
    322   } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
    323   void operator++() {
    324     wmu.Lock(); // expected-note {{mutex acquired here}}
    325   } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
    326   operator int*() {
    327     wmu.Lock(); // expected-note {{mutex acquired here}}
    328     return 0;
    329   } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
    330 };
    331 
    332 //-----------------------------------------------//
    333 // Errors for guarded by or guarded var variables
    334 // ----------------------------------------------//
    335 
    336 int *pgb_gvar __attribute__((pt_guarded_var));
    337 int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
    338 
    339 class PGBFoo {
    340  public:
    341   int x;
    342   int *pgb_field __attribute__((guarded_by(sls_mu2)))
    343                  __attribute__((pt_guarded_by(sls_mu)));
    344   void testFoo() {
    345     pgb_field = &x; // \
    346       // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
    347     *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
    348       // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
    349     x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
    350       // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
    351     (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
    352       // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
    353   }
    354 };
    355 
    356 class GBFoo {
    357  public:
    358   int gb_field __attribute__((guarded_by(sls_mu)));
    359 
    360   void testFoo() {
    361     gb_field = 0; // \
    362       // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
    363   }
    364 
    365   void testNoAnal() __attribute__((no_thread_safety_analysis)) {
    366     gb_field = 0;
    367   }
    368 };
    369 
    370 GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
    371 
    372 void gb_fun_0() {
    373   sls_mu.Lock();
    374   int x = *pgb_var;
    375   sls_mu.Unlock();
    376 }
    377 
    378 void gb_fun_1() {
    379   sls_mu.Lock();
    380   *pgb_var = 2;
    381   sls_mu.Unlock();
    382 }
    383 
    384 void gb_fun_2() {
    385   int x;
    386   pgb_var = &x;
    387 }
    388 
    389 void gb_fun_3() {
    390   int *x = pgb_var;
    391 }
    392 
    393 void gb_bad_0() {
    394   sls_guard_var = 1; // \
    395     // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
    396 }
    397 
    398 void gb_bad_1() {
    399   int x = sls_guard_var; // \
    400     // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
    401 }
    402 
    403 void gb_bad_2() {
    404   sls_guardby_var = 1; // \
    405     // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
    406 }
    407 
    408 void gb_bad_3() {
    409   int x = sls_guardby_var; // \
    410     // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
    411 }
    412 
    413 void gb_bad_4() {
    414   *pgb_gvar = 1; // \
    415     // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
    416 }
    417 
    418 void gb_bad_5() {
    419   int x = *pgb_gvar; // \
    420     // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
    421 }
    422 
    423 void gb_bad_6() {
    424   *pgb_var = 1; // \
    425     // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
    426 }
    427 
    428 void gb_bad_7() {
    429   int x = *pgb_var; // \
    430     // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
    431 }
    432 
    433 void gb_bad_8() {
    434   GBFoo G;
    435   G.gb_field = 0; // \
    436     // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
    437 }
    438 
    439 void gb_bad_9() {
    440   sls_guard_var++; // \
    441     // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
    442   sls_guard_var--; // \
    443     // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
    444   ++sls_guard_var; // \
    445     // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
    446   --sls_guard_var;// \
    447     // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
    448 }
    449 
    450 //-----------------------------------------------//
    451 // Warnings on variables with late parsed attributes
    452 // ----------------------------------------------//
    453 
    454 class LateFoo {
    455 public:
    456   int a __attribute__((guarded_by(mu)));
    457   int b;
    458 
    459   void foo() __attribute__((exclusive_locks_required(mu))) { }
    460 
    461   void test() {
    462     a = 0; // \
    463       // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
    464     b = a; // \
    465       // expected-warning {{reading variable 'a' requires locking 'mu'}}
    466     c = 0; // \
    467       // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
    468   }
    469 
    470   int c __attribute__((guarded_by(mu)));
    471 
    472   Mutex mu;
    473 };
    474 
    475 class LateBar {
    476  public:
    477   int a_ __attribute__((guarded_by(mu1_)));
    478   int b_;
    479   int *q __attribute__((pt_guarded_by(mu)));
    480   Mutex mu1_;
    481   Mutex mu;
    482   LateFoo Foo;
    483   LateFoo Foo2;
    484   LateFoo *FooPointer;
    485 };
    486 
    487 LateBar b1, *b3;
    488 
    489 void late_0() {
    490   LateFoo FooA;
    491   LateFoo FooB;
    492   FooA.mu.Lock();
    493   FooA.a = 5;
    494   FooA.mu.Unlock();
    495 }
    496 
    497 void late_1() {
    498   LateBar BarA;
    499   BarA.FooPointer->mu.Lock();
    500   BarA.FooPointer->a = 2;
    501   BarA.FooPointer->mu.Unlock();
    502 }
    503 
    504 void late_bad_0() {
    505   LateFoo fooA;
    506   LateFoo fooB;
    507   fooA.mu.Lock();
    508   fooB.a = 5; // \
    509     // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
    510   fooA.mu.Unlock();
    511 }
    512 
    513 void late_bad_1() {
    514   Mutex mu;
    515   mu.Lock();
    516   b1.mu1_.Lock();
    517   int res = b1.a_ + b3->b_;
    518   b3->b_ = *b1.q; // \
    519     // expected-warning{{reading the value pointed to by 'q' requires locking 'mu'}}
    520   b1.mu1_.Unlock();
    521   b1.b_ = res;
    522   mu.Unlock();
    523 }
    524 
    525 void late_bad_2() {
    526   LateBar BarA;
    527   BarA.FooPointer->mu.Lock();
    528   BarA.Foo.a = 2; // \
    529     // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
    530   BarA.FooPointer->mu.Unlock();
    531 }
    532 
    533 void late_bad_3() {
    534   LateBar BarA;
    535   BarA.Foo.mu.Lock();
    536   BarA.FooPointer->a = 2; // \
    537     // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
    538   BarA.Foo.mu.Unlock();
    539 }
    540 
    541 void late_bad_4() {
    542   LateBar BarA;
    543   BarA.Foo.mu.Lock();
    544   BarA.Foo2.a = 2; // \
    545     // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
    546   BarA.Foo.mu.Unlock();
    547 }
    548 
    549 //-----------------------------------------------//
    550 // Extra warnings for shared vs. exclusive locks
    551 // ----------------------------------------------//
    552 
    553 void shared_fun_0() {
    554   sls_mu.Lock();
    555   do {
    556     sls_mu.Unlock();
    557     sls_mu.Lock();
    558   } while (getBool());
    559   sls_mu.Unlock();
    560 }
    561 
    562 void shared_fun_1() {
    563   sls_mu.ReaderLock(); // \
    564     // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
    565   do {
    566     sls_mu.Unlock();
    567     sls_mu.Lock();  // \
    568       // expected-note {{the other lock of mutex 'sls_mu' is here}}
    569   } while (getBool());
    570   sls_mu.Unlock();
    571 }
    572 
    573 void shared_fun_3() {
    574   if (getBool())
    575     sls_mu.Lock();
    576   else
    577     sls_mu.Lock();
    578   *pgb_var = 1;
    579   sls_mu.Unlock();
    580 }
    581 
    582 void shared_fun_4() {
    583   if (getBool())
    584     sls_mu.ReaderLock();
    585   else
    586     sls_mu.ReaderLock();
    587   int x = sls_guardby_var;
    588   sls_mu.Unlock();
    589 }
    590 
    591 void shared_fun_8() {
    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   sls_mu.Unlock();
    599 }
    600 
    601 void shared_bad_0() {
    602   sls_mu.Lock();  // \
    603     // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
    604   do {
    605     sls_mu.Unlock();
    606     sls_mu.ReaderLock();  // \
    607       // expected-note {{the other lock of mutex 'sls_mu' is here}}
    608   } while (getBool());
    609   sls_mu.Unlock();
    610 }
    611 
    612 void shared_bad_1() {
    613   if (getBool())
    614     sls_mu.Lock(); // \
    615       // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
    616   else
    617     sls_mu.ReaderLock(); // \
    618       // expected-note {{the other lock of mutex 'sls_mu' is here}}
    619   *pgb_var = 1;
    620   sls_mu.Unlock();
    621 }
    622 
    623 void shared_bad_2() {
    624   if (getBool())
    625     sls_mu.ReaderLock(); // \
    626       // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
    627   else
    628     sls_mu.Lock(); // \
    629       // expected-note {{the other lock of mutex 'sls_mu' is here}}
    630   *pgb_var = 1;
    631   sls_mu.Unlock();
    632 }
    633 
    634 // FIXME: Add support for functions (not only methods)
    635 class LRBar {
    636  public:
    637   void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
    638   void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
    639   void le_fun() __attribute__((locks_excluded(sls_mu)));
    640 };
    641 
    642 class LRFoo {
    643  public:
    644   void test() __attribute__((exclusive_locks_required(sls_mu)));
    645   void testShared() __attribute__((shared_locks_required(sls_mu2)));
    646 };
    647 
    648 void elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
    649 void elr_fun() {}
    650 
    651 LRFoo MyLRFoo;
    652 LRBar Bar;
    653 
    654 void es_fun_0() {
    655   aa_mu.Lock();
    656   Bar.aa_elr_fun();
    657   aa_mu.Unlock();
    658 }
    659 
    660 void es_fun_1() {
    661   aa_mu.Lock();
    662   Bar.aa_elr_fun_s();
    663   aa_mu.Unlock();
    664 }
    665 
    666 void es_fun_2() {
    667   aa_mu.ReaderLock();
    668   Bar.aa_elr_fun_s();
    669   aa_mu.Unlock();
    670 }
    671 
    672 void es_fun_3() {
    673   sls_mu.Lock();
    674   MyLRFoo.test();
    675   sls_mu.Unlock();
    676 }
    677 
    678 void es_fun_4() {
    679   sls_mu2.Lock();
    680   MyLRFoo.testShared();
    681   sls_mu2.Unlock();
    682 }
    683 
    684 void es_fun_5() {
    685   sls_mu2.ReaderLock();
    686   MyLRFoo.testShared();
    687   sls_mu2.Unlock();
    688 }
    689 
    690 void es_fun_6() {
    691   Bar.le_fun();
    692 }
    693 
    694 void es_fun_7() {
    695   sls_mu.Lock();
    696   elr_fun();
    697   sls_mu.Unlock();
    698 }
    699 
    700 void es_fun_8() __attribute__((no_thread_safety_analysis));
    701 
    702 void es_fun_8() {
    703   Bar.aa_elr_fun_s();
    704 }
    705 
    706 void es_fun_9() __attribute__((shared_locks_required(aa_mu)));
    707 void es_fun_9() {
    708   Bar.aa_elr_fun_s();
    709 }
    710 
    711 void es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
    712 void es_fun_10() {
    713   Bar.aa_elr_fun_s();
    714 }
    715 
    716 void es_bad_0() {
    717   Bar.aa_elr_fun(); // \
    718     // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
    719 }
    720 
    721 void es_bad_1() {
    722   aa_mu.ReaderLock();
    723   Bar.aa_elr_fun(); // \
    724     // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
    725   aa_mu.Unlock();
    726 }
    727 
    728 void es_bad_2() {
    729   Bar.aa_elr_fun_s(); // \
    730     // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
    731 }
    732 
    733 void es_bad_3() {
    734   MyLRFoo.test(); // \
    735     // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
    736 }
    737 
    738 void es_bad_4() {
    739   MyLRFoo.testShared(); // \
    740     // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
    741 }
    742 
    743 void es_bad_5() {
    744   sls_mu.ReaderLock();
    745   MyLRFoo.test(); // \
    746     // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
    747   sls_mu.Unlock();
    748 }
    749 
    750 void es_bad_6() {
    751   sls_mu.Lock();
    752   Bar.le_fun(); // \
    753     // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
    754   sls_mu.Unlock();
    755 }
    756 
    757 void es_bad_7() {
    758   sls_mu.ReaderLock();
    759   Bar.le_fun(); // \
    760     // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
    761   sls_mu.Unlock();
    762 }
    763 
    764 
    765 //-----------------------------------------------//
    766 // Unparseable lock expressions
    767 // ----------------------------------------------//
    768 
    769 // FIXME -- derive new tests for unhandled expressions
    770 
    771 
    772 //----------------------------------------------------------------------------//
    773 // The following test cases are ported from the gcc thread safety implementation
    774 // They are each wrapped inside a namespace with the test number of the gcc test
    775 //
    776 // FIXME: add all the gcc tests, once this analysis passes them.
    777 //----------------------------------------------------------------------------//
    778 
    779 //-----------------------------------------//
    780 // Good testcases (no errors)
    781 //-----------------------------------------//
    782 
    783 namespace thread_annot_lock_20 {
    784 class Bar {
    785  public:
    786   static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
    787   static int b_ GUARDED_BY(mu1_);
    788   static Mutex mu1_;
    789   static int a_ GUARDED_BY(mu1_);
    790 };
    791 
    792 Bar b1;
    793 
    794 int Bar::func1()
    795 {
    796   int res = 5;
    797 
    798   if (a_ == 4)
    799     res = b_;
    800   return res;
    801 }
    802 } // end namespace thread_annot_lock_20
    803 
    804 namespace thread_annot_lock_22 {
    805 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
    806 // uses in class definitions.
    807 Mutex mu;
    808 
    809 class Bar {
    810  public:
    811   int a_ GUARDED_BY(mu1_);
    812   int b_;
    813   int *q PT_GUARDED_BY(mu);
    814   Mutex mu1_ ACQUIRED_AFTER(mu);
    815 };
    816 
    817 Bar b1, *b3;
    818 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
    819 int res GUARDED_BY(mu) = 5;
    820 
    821 int func(int i)
    822 {
    823   int x;
    824   mu.Lock();
    825   b1.mu1_.Lock();
    826   res = b1.a_ + b3->b_;
    827   *p = i;
    828   b1.a_ = res + b3->b_;
    829   b3->b_ = *b1.q;
    830   b1.mu1_.Unlock();
    831   b1.b_ = res;
    832   x = res;
    833   mu.Unlock();
    834   return x;
    835 }
    836 } // end namespace thread_annot_lock_22
    837 
    838 namespace thread_annot_lock_27_modified {
    839 // test lock annotations applied to function definitions
    840 // Modified: applied annotations only to function declarations
    841 Mutex mu1;
    842 Mutex mu2 ACQUIRED_AFTER(mu1);
    843 
    844 class Foo {
    845  public:
    846   int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
    847 };
    848 
    849 int Foo::method1(int i) {
    850   return i;
    851 }
    852 
    853 
    854 int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
    855 int foo(int i) {
    856   return i;
    857 }
    858 
    859 static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
    860 static int bar(int i) {
    861   return i;
    862 }
    863 
    864 void main() {
    865   Foo a;
    866 
    867   mu1.Lock();
    868   mu2.Lock();
    869   a.method1(1);
    870   foo(2);
    871   mu2.Unlock();
    872   bar(3);
    873   mu1.Unlock();
    874 }
    875 } // end namespace thread_annot_lock_27_modified
    876 
    877 
    878 namespace thread_annot_lock_38 {
    879 // Test the case where a template member function is annotated with lock
    880 // attributes in a non-template class.
    881 class Foo {
    882  public:
    883   void func1(int y) LOCKS_EXCLUDED(mu_);
    884   template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
    885  private:
    886   Mutex mu_;
    887 };
    888 
    889 Foo *foo;
    890 
    891 void main()
    892 {
    893   foo->func1(5);
    894   foo->func2(5);
    895 }
    896 } // end namespace thread_annot_lock_38
    897 
    898 namespace thread_annot_lock_43 {
    899 // Tests lock canonicalization
    900 class Foo {
    901  public:
    902   Mutex *mu_;
    903 };
    904 
    905 class FooBar {
    906  public:
    907   Foo *foo_;
    908   int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
    909   int a_ GUARDED_BY(foo_->mu_);
    910 };
    911 
    912 FooBar *fb;
    913 
    914 void main()
    915 {
    916   int x;
    917   fb->foo_->mu_->Lock();
    918   x = fb->GetA();
    919   fb->foo_->mu_->Unlock();
    920 }
    921 } // end namespace thread_annot_lock_43
    922 
    923 namespace thread_annot_lock_49 {
    924 // Test the support for use of lock expression in the annotations
    925 class Foo {
    926  public:
    927   Mutex foo_mu_;
    928 };
    929 
    930 class Bar {
    931  private:
    932   Foo *foo;
    933   Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
    934 
    935  public:
    936   void Test1() {
    937     foo->foo_mu_.Lock();
    938     bar_mu_.Lock();
    939     bar_mu_.Unlock();
    940     foo->foo_mu_.Unlock();
    941   }
    942 };
    943 
    944 void main() {
    945   Bar bar;
    946   bar.Test1();
    947 }
    948 } // end namespace thread_annot_lock_49
    949 
    950 namespace thread_annot_lock_61_modified {
    951   // Modified to fix the compiler errors
    952   // Test the fix for a bug introduced by the support of pass-by-reference
    953   // paramters.
    954   struct Foo { Foo &operator<< (bool) {return *this;} };
    955   Foo &getFoo();
    956   struct Bar { Foo &func () {return getFoo();} };
    957   struct Bas { void operator& (Foo &) {} };
    958   void mumble()
    959   {
    960     Bas() & Bar().func() << "" << "";
    961     Bas() & Bar().func() << "";
    962   }
    963 } // end namespace thread_annot_lock_61_modified
    964 
    965 
    966 namespace thread_annot_lock_65 {
    967 // Test the fix for a bug in the support of allowing reader locks for
    968 // non-const, non-modifying overload functions. (We didn't handle the builtin
    969 // properly.)
    970 enum MyFlags {
    971   Zero,
    972   One,
    973   Two,
    974   Three,
    975   Four,
    976   Five,
    977   Six,
    978   Seven,
    979   Eight,
    980   Nine
    981 };
    982 
    983 inline MyFlags
    984 operator|(MyFlags a, MyFlags b)
    985 {
    986   return MyFlags(static_cast<int>(a) | static_cast<int>(b));
    987 }
    988 
    989 inline MyFlags&
    990 operator|=(MyFlags& a, MyFlags b)
    991 {
    992     return a = a | b;
    993 }
    994 } // end namespace thread_annot_lock_65
    995 
    996 namespace thread_annot_lock_66_modified {
    997 // Modified: Moved annotation to function defn
    998 // Test annotations on out-of-line definitions of member functions where the
    999 // annotations refer to locks that are also data members in the class.
   1000 Mutex mu;
   1001 
   1002 class Foo {
   1003  public:
   1004   int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
   1005   int data GUARDED_BY(mu1);
   1006   Mutex *mu1;
   1007   Mutex *mu2;
   1008 };
   1009 
   1010 int Foo::method1(int i)
   1011 {
   1012   return data + i;
   1013 }
   1014 
   1015 void main()
   1016 {
   1017   Foo a;
   1018 
   1019   a.mu2->Lock();
   1020   a.mu1->Lock();
   1021   mu.Lock();
   1022   a.method1(1);
   1023   mu.Unlock();
   1024   a.mu1->Unlock();
   1025   a.mu2->Unlock();
   1026 }
   1027 } // end namespace thread_annot_lock_66_modified
   1028 
   1029 namespace thread_annot_lock_68_modified {
   1030 // Test a fix to a bug in the delayed name binding with nested template
   1031 // instantiation. We use a stack to make sure a name is not resolved to an
   1032 // inner context.
   1033 template <typename T>
   1034 class Bar {
   1035   Mutex mu_;
   1036 };
   1037 
   1038 template <typename T>
   1039 class Foo {
   1040  public:
   1041   void func(T x) {
   1042     mu_.Lock();
   1043     count_ = x;
   1044     mu_.Unlock();
   1045   }
   1046 
   1047  private:
   1048   T count_ GUARDED_BY(mu_);
   1049   Bar<T> bar_;
   1050   Mutex mu_;
   1051 };
   1052 
   1053 void main()
   1054 {
   1055   Foo<int> *foo;
   1056   foo->func(5);
   1057 }
   1058 } // end namespace thread_annot_lock_68_modified
   1059 
   1060 namespace thread_annot_lock_30_modified {
   1061 // Test delay parsing of lock attribute arguments with nested classes.
   1062 // Modified: trylocks replaced with exclusive_lock_fun
   1063 int a = 0;
   1064 
   1065 class Bar {
   1066   struct Foo;
   1067 
   1068  public:
   1069   void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
   1070 
   1071   int func() {
   1072     MyLock();
   1073 //    if (foo == 0) {
   1074 //      return 0;
   1075 //    }
   1076     a = 5;
   1077     mu.Unlock();
   1078     return 1;
   1079   }
   1080 
   1081   class FooBar {
   1082     int x;
   1083     int y;
   1084   };
   1085 
   1086  private:
   1087   Mutex mu;
   1088 };
   1089 
   1090 Bar *bar;
   1091 
   1092 void main()
   1093 {
   1094   bar->func();
   1095 }
   1096 } // end namespace thread_annot_lock_30_modified
   1097 
   1098 namespace thread_annot_lock_47 {
   1099 // Test the support for annotations on virtual functions.
   1100 // This is a good test case. (i.e. There should be no warning emitted by the
   1101 // compiler.)
   1102 class Base {
   1103  public:
   1104   virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
   1105   virtual void func2() LOCKS_EXCLUDED(mu_);
   1106   Mutex mu_;
   1107 };
   1108 
   1109 class Child : public Base {
   1110  public:
   1111   virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
   1112   virtual void func2() LOCKS_EXCLUDED(mu_);
   1113 };
   1114 
   1115 void main() {
   1116   Child *c;
   1117   Base *b = c;
   1118 
   1119   b->mu_.Lock();
   1120   b->func1();
   1121   b->mu_.Unlock();
   1122   b->func2();
   1123 
   1124   c->mu_.Lock();
   1125   c->func1();
   1126   c->mu_.Unlock();
   1127   c->func2();
   1128 }
   1129 } // end namespace thread_annot_lock_47
   1130 
   1131 //-----------------------------------------//
   1132 // Tests which produce errors
   1133 //-----------------------------------------//
   1134 
   1135 namespace thread_annot_lock_13 {
   1136 Mutex mu1;
   1137 Mutex mu2;
   1138 
   1139 int g GUARDED_BY(mu1);
   1140 int w GUARDED_BY(mu2);
   1141 
   1142 class Foo {
   1143  public:
   1144   void bar() LOCKS_EXCLUDED(mu_, mu1);
   1145   int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
   1146 
   1147  private:
   1148   int a_ GUARDED_BY(mu_);
   1149  public:
   1150   Mutex mu_ ACQUIRED_AFTER(mu1);
   1151 };
   1152 
   1153 int Foo::foo()
   1154 {
   1155   int res;
   1156   w = 5;
   1157   res = a_ + 5;
   1158   return res;
   1159 }
   1160 
   1161 void Foo::bar()
   1162 {
   1163   int x;
   1164   mu_.Lock();
   1165   x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
   1166   a_ = x + 1;
   1167   mu_.Unlock();
   1168   if (x > 5) {
   1169     mu1.Lock();
   1170     g = 2;
   1171     mu1.Unlock();
   1172   }
   1173 }
   1174 
   1175 void main()
   1176 {
   1177   Foo f1, *f2;
   1178   f1.mu_.Lock();
   1179   f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
   1180   mu2.Lock();
   1181   f1.foo();
   1182   mu2.Unlock();
   1183   f1.mu_.Unlock();
   1184   f2->mu_.Lock();
   1185   f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
   1186   f2->mu_.Unlock();
   1187   mu2.Lock();
   1188   w = 2;
   1189   mu2.Unlock();
   1190 }
   1191 } // end namespace thread_annot_lock_13
   1192 
   1193 namespace thread_annot_lock_18_modified {
   1194 // Modified: Trylocks removed
   1195 // Test the ability to distnguish between the same lock field of
   1196 // different objects of a class.
   1197   class Bar {
   1198  public:
   1199   bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
   1200   void MyUnlock() UNLOCK_FUNCTION(mu1_);
   1201   int a_ GUARDED_BY(mu1_);
   1202 
   1203  private:
   1204   Mutex mu1_;
   1205 };
   1206 
   1207 Bar *b1, *b2;
   1208 
   1209 void func()
   1210 {
   1211   b1->MyLock();
   1212   b1->a_ = 5;
   1213   b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
   1214   b2->MyLock();
   1215   b2->MyUnlock();
   1216   b1->MyUnlock();
   1217 }
   1218 } // end namespace thread_annot_lock_18_modified
   1219 
   1220 namespace thread_annot_lock_21 {
   1221 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
   1222 // uses in class definitions.
   1223 Mutex mu;
   1224 
   1225 class Bar {
   1226  public:
   1227   int a_ GUARDED_BY(mu1_);
   1228   int b_;
   1229   int *q PT_GUARDED_BY(mu);
   1230   Mutex mu1_ ACQUIRED_AFTER(mu);
   1231 };
   1232 
   1233 Bar b1, *b3;
   1234 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
   1235 
   1236 int res GUARDED_BY(mu) = 5;
   1237 
   1238 int func(int i)
   1239 {
   1240   int x;
   1241   b3->mu1_.Lock();
   1242   res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'mu1_'}} \
   1243     // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}}
   1244   *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
   1245     // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
   1246   b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
   1247     // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
   1248   b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
   1249   b3->mu1_.Unlock();
   1250   b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
   1251   x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
   1252   return x;
   1253 }
   1254 } // end namespace thread_annot_lock_21
   1255 
   1256 namespace thread_annot_lock_35_modified {
   1257 // Test the analyzer's ability to distinguish the lock field of different
   1258 // objects.
   1259 class Foo {
   1260  private:
   1261   Mutex lock_;
   1262   int a_ GUARDED_BY(lock_);
   1263 
   1264  public:
   1265   void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
   1266      Foo *new_foo = new Foo;
   1267 
   1268      lock_.Lock();
   1269 
   1270      child->Func(new_foo); // There shouldn't be any warning here as the
   1271                            // acquired lock is not in child.
   1272      child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'lock_'}}
   1273      child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'lock_' exclusively}}
   1274      lock_.Unlock();
   1275   }
   1276 
   1277   void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
   1278     a_ = y;
   1279   }
   1280 };
   1281 
   1282 Foo *x;
   1283 
   1284 void main() {
   1285   Foo *child = new Foo;
   1286   x->Func(child);
   1287 }
   1288 } // end namespace thread_annot_lock_35_modified
   1289 
   1290 namespace thread_annot_lock_36_modified {
   1291 // Modified to move the annotations to function defns.
   1292 // Test the analyzer's ability to distinguish the lock field of different
   1293 // objects
   1294 class Foo {
   1295  private:
   1296   Mutex lock_;
   1297   int a_ GUARDED_BY(lock_);
   1298 
   1299  public:
   1300   void Func(Foo* child) LOCKS_EXCLUDED(lock_);
   1301   void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
   1302 };
   1303 
   1304 void Foo::Func(Foo* child) {
   1305   Foo *new_foo = new Foo;
   1306 
   1307   lock_.Lock();
   1308 
   1309   child->lock_.Lock();
   1310   child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'lock_' is locked}}
   1311   child->bar(7);
   1312   child->a_ = 5;
   1313   child->lock_.Unlock();
   1314 
   1315   lock_.Unlock();
   1316 }
   1317 
   1318 void Foo::bar(int y) {
   1319   a_ = y;
   1320 }
   1321 
   1322 
   1323 Foo *x;
   1324 
   1325 void main() {
   1326   Foo *child = new Foo;
   1327   x->Func(child);
   1328 }
   1329 } // end namespace thread_annot_lock_36_modified
   1330 
   1331 
   1332 namespace thread_annot_lock_42 {
   1333 // Test support of multiple lock attributes of the same kind on a decl.
   1334 class Foo {
   1335  private:
   1336   Mutex mu1, mu2, mu3;
   1337   int x GUARDED_BY(mu1) GUARDED_BY(mu2);
   1338   int y GUARDED_BY(mu2);
   1339 
   1340   void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
   1341     mu2.Lock();
   1342     y = 2;
   1343     mu2.Unlock();
   1344   }
   1345 
   1346  public:
   1347   void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
   1348     x = 5;
   1349     f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
   1350       // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
   1351   }
   1352 };
   1353 
   1354 Foo *foo;
   1355 
   1356 void func()
   1357 {
   1358   foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'mu2'}} \
   1359     // expected-warning {{calling function 'f1' requires exclusive lock on 'mu1'}}
   1360 }
   1361 } // end namespace thread_annot_lock_42
   1362 
   1363 namespace thread_annot_lock_46 {
   1364 // Test the support for annotations on virtual functions.
   1365 class Base {
   1366  public:
   1367   virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
   1368   virtual void func2() LOCKS_EXCLUDED(mu_);
   1369   Mutex mu_;
   1370 };
   1371 
   1372 class Child : public Base {
   1373  public:
   1374   virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
   1375   virtual void func2() LOCKS_EXCLUDED(mu_);
   1376 };
   1377 
   1378 void main() {
   1379   Child *c;
   1380   Base *b = c;
   1381 
   1382   b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
   1383   b->mu_.Lock();
   1384   b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
   1385   b->mu_.Unlock();
   1386 
   1387   c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
   1388   c->mu_.Lock();
   1389   c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
   1390   c->mu_.Unlock();
   1391 }
   1392 } // end namespace thread_annot_lock_46
   1393 
   1394 namespace thread_annot_lock_67_modified {
   1395 // Modified: attributes on definitions moved to declarations
   1396 // Test annotations on out-of-line definitions of member functions where the
   1397 // annotations refer to locks that are also data members in the class.
   1398 Mutex mu;
   1399 Mutex mu3;
   1400 
   1401 class Foo {
   1402  public:
   1403   int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
   1404   int data GUARDED_BY(mu1);
   1405   Mutex *mu1;
   1406   Mutex *mu2;
   1407 };
   1408 
   1409 int Foo::method1(int i) {
   1410   return data + i;
   1411 }
   1412 
   1413 void main()
   1414 {
   1415   Foo a;
   1416   a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'mu1'}} \
   1417     // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
   1418     // expected-warning {{calling function 'method1' requires shared lock on 'mu2'}} \
   1419     // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
   1420 }
   1421 } // end namespace thread_annot_lock_67_modified
   1422 
   1423 
   1424 namespace substitution_test {
   1425   class MyData  {
   1426   public:
   1427     Mutex mu;
   1428 
   1429     void lockData()    __attribute__((exclusive_lock_function(mu)))   { }
   1430     void unlockData()  __attribute__((unlock_function(mu)))           { }
   1431 
   1432     void doSomething() __attribute__((exclusive_locks_required(mu)))  { }
   1433   };
   1434 
   1435 
   1436   class DataLocker {
   1437   public:
   1438     void lockData  (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { }
   1439     void unlockData(MyData *d) __attribute__((unlock_function(d->mu)))         { }
   1440   };
   1441 
   1442 
   1443   class Foo {
   1444   public:
   1445     void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
   1446 
   1447     void bar1(MyData* d) {
   1448       d->lockData();
   1449       foo(d);
   1450       d->unlockData();
   1451     }
   1452 
   1453     void bar2(MyData* d) {
   1454       DataLocker dlr;
   1455       dlr.lockData(d);
   1456       foo(d);
   1457       dlr.unlockData(d);
   1458     }
   1459 
   1460     void bar3(MyData* d1, MyData* d2) {
   1461       DataLocker dlr;
   1462       dlr.lockData(d1);   // expected-note {{mutex acquired here}}
   1463       dlr.unlockData(d2); // \
   1464         // expected-warning {{unlocking 'mu' that was not locked}}
   1465     } // expected-warning {{mutex 'mu' is still locked at the end of function}}
   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 
   1553 namespace test_scoped_lockable {
   1554 
   1555 struct TestScopedLockable {
   1556   Mutex mu1;
   1557   Mutex mu2;
   1558   int a __attribute__((guarded_by(mu1)));
   1559   int b __attribute__((guarded_by(mu2)));
   1560 
   1561   bool getBool();
   1562 
   1563   void foo1() {
   1564     MutexLock mulock(&mu1);
   1565     a = 5;
   1566   }
   1567 
   1568   void foo2() {
   1569     ReaderMutexLock mulock1(&mu1);
   1570     if (getBool()) {
   1571       MutexLock mulock2a(&mu2);
   1572       b = a + 1;
   1573     }
   1574     else {
   1575       MutexLock mulock2b(&mu2);
   1576       b = a + 2;
   1577     }
   1578   }
   1579 
   1580   void foo3() {
   1581     MutexLock mulock_a(&mu1);
   1582     MutexLock mulock_b(&mu1); // \
   1583       // expected-warning {{locking 'mu1' that is already locked}}
   1584   }   // expected-warning {{unlocking 'mu1' that was not locked}}
   1585 
   1586   void foo4() {
   1587     MutexLock mulock1(&mu1), mulock2(&mu2);
   1588     a = b+1;
   1589     b = a+1;
   1590   }
   1591 };
   1592 
   1593 } // end namespace test_scoped_lockable
   1594 
   1595 
   1596 namespace FunctionAttrTest {
   1597 
   1598 class Foo {
   1599 public:
   1600   Mutex mu_;
   1601   int a GUARDED_BY(mu_);
   1602 };
   1603 
   1604 Foo fooObj;
   1605 
   1606 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
   1607 
   1608 void bar() {
   1609   foo();  // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
   1610   fooObj.mu_.Lock();
   1611   foo();
   1612   fooObj.mu_.Unlock();
   1613 }
   1614 
   1615 };  // end namespace FunctionAttrTest
   1616 
   1617 
   1618 struct TestTryLock {
   1619   Mutex mu;
   1620   int a GUARDED_BY(mu);
   1621   bool cond;
   1622 
   1623   void foo1() {
   1624     if (mu.TryLock()) {
   1625       a = 1;
   1626       mu.Unlock();
   1627     }
   1628   }
   1629 
   1630   void foo2() {
   1631     if (!mu.TryLock()) return;
   1632     a = 2;
   1633     mu.Unlock();
   1634   }
   1635 
   1636   void foo3() {
   1637     bool b = mu.TryLock();
   1638     if (b) {
   1639       a = 3;
   1640       mu.Unlock();
   1641     }
   1642   }
   1643 
   1644   void foo4() {
   1645     bool b = mu.TryLock();
   1646     if (!b) return;
   1647     a = 4;
   1648     mu.Unlock();
   1649   }
   1650 
   1651   void foo5() {
   1652     while (mu.TryLock()) {
   1653       a = a + 1;
   1654       mu.Unlock();
   1655     }
   1656   }
   1657 
   1658   void foo6() {
   1659     bool b = mu.TryLock();
   1660     b = !b;
   1661     if (b) return;
   1662     a = 6;
   1663     mu.Unlock();
   1664   }
   1665 
   1666   void foo7() {
   1667     bool b1 = mu.TryLock();
   1668     bool b2 = !b1;
   1669     bool b3 = !b2;
   1670     if (b3) {
   1671       a = 7;
   1672       mu.Unlock();
   1673     }
   1674   }
   1675 
   1676   // Test use-def chains: join points
   1677   void foo8() {
   1678     bool b  = mu.TryLock();
   1679     bool b2 = b;
   1680     if (cond)
   1681       b = true;
   1682     if (b) {    // b should be unknown at this point, becuase of the join point
   1683       a = 8;    // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
   1684     }
   1685     if (b2) {   // b2 should be known at this point.
   1686       a = 8;
   1687       mu.Unlock();
   1688     }
   1689   }
   1690 
   1691   // Test use-def-chains: back edges
   1692   void foo9() {
   1693     bool b = mu.TryLock();
   1694 
   1695     for (int i = 0; i < 10; ++i);
   1696 
   1697     if (b) {  // b is still known, because the loop doesn't alter it
   1698       a = 9;
   1699       mu.Unlock();
   1700     }
   1701   }
   1702 
   1703   // Test use-def chains: back edges
   1704   void foo10() {
   1705     bool b = mu.TryLock();
   1706 
   1707     while (cond) {
   1708       if (b) {   // b should be uknown at this point b/c of the loop
   1709         a = 10;  // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
   1710       }
   1711       b = !b;
   1712     }
   1713   }
   1714 };  // end TestTrylock
   1715 
   1716 
   1717 namespace TestTemplateAttributeInstantiation {
   1718 
   1719 class Foo1 {
   1720 public:
   1721   Mutex mu_;
   1722   int a GUARDED_BY(mu_);
   1723 };
   1724 
   1725 class Foo2 {
   1726 public:
   1727   int a GUARDED_BY(mu_);
   1728   Mutex mu_;
   1729 };
   1730 
   1731 
   1732 class Bar {
   1733 public:
   1734   // Test non-dependent expressions in attributes on template functions
   1735   template <class T>
   1736   void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
   1737     foo->a = 0;
   1738   }
   1739 
   1740   // Test dependent expressions in attributes on template functions
   1741   template <class T>
   1742   void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
   1743     fooT->a = 0;
   1744   }
   1745 };
   1746 
   1747 
   1748 template <class T>
   1749 class BarT {
   1750 public:
   1751   Foo1 fooBase;
   1752   T    fooBaseT;
   1753 
   1754   // Test non-dependent expression in ordinary method on template class
   1755   void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
   1756     fooBase.a = 0;
   1757   }
   1758 
   1759   // Test dependent expressions in ordinary methods on template class
   1760   void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
   1761     fooBaseT.a = 0;
   1762   }
   1763 
   1764   // Test dependent expressions in template method in template class
   1765   template <class T2>
   1766   void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
   1767     fooBaseT.a = 0;
   1768     fooT->a = 0;
   1769   }
   1770 };
   1771 
   1772 template <class T>
   1773 class Cell {
   1774 public:
   1775   Mutex mu_;
   1776   // Test dependent guarded_by
   1777   T data GUARDED_BY(mu_);
   1778 
   1779   void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
   1780     data = 0;
   1781   }
   1782 
   1783   void foo() {
   1784     mu_.Lock();
   1785     data = 0;
   1786     mu_.Unlock();
   1787   }
   1788 };
   1789 
   1790 void test() {
   1791   Bar b;
   1792   BarT<Foo2> bt;
   1793   Foo1 f1;
   1794   Foo2 f2;
   1795 
   1796   f1.mu_.Lock();
   1797   f2.mu_.Lock();
   1798   bt.fooBase.mu_.Lock();
   1799   bt.fooBaseT.mu_.Lock();
   1800 
   1801   b.barND(&f1, &f2);
   1802   b.barD(&f1, &f2);
   1803   bt.barND();
   1804   bt.barD();
   1805   bt.barTD(&f2);
   1806 
   1807   f1.mu_.Unlock();
   1808   bt.barTD(&f1);  // \
   1809     // expected-warning {{calling function 'barTD' requires exclusive lock on 'mu_'}}
   1810 
   1811   bt.fooBase.mu_.Unlock();
   1812   bt.fooBaseT.mu_.Unlock();
   1813   f2.mu_.Unlock();
   1814 
   1815   Cell<int> cell;
   1816   cell.data = 0; // \
   1817     // expected-warning {{writing variable 'data' requires locking 'mu_' exclusively}}
   1818   cell.foo();
   1819   cell.mu_.Lock();
   1820   cell.fooEx();
   1821   cell.mu_.Unlock();
   1822 }
   1823 
   1824 
   1825 template <class T>
   1826 class CellDelayed {
   1827 public:
   1828   // Test dependent guarded_by
   1829   T data GUARDED_BY(mu_);
   1830   static T static_data GUARDED_BY(static_mu_);
   1831 
   1832   void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
   1833     this->data = other->data;
   1834   }
   1835 
   1836   template <class T2>
   1837   void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
   1838     this->data = otherT->data;
   1839   }
   1840 
   1841   void foo() {
   1842     mu_.Lock();
   1843     data = 0;
   1844     mu_.Unlock();
   1845   }
   1846 
   1847   Mutex mu_;
   1848   static Mutex static_mu_;
   1849 };
   1850 
   1851 void testDelayed() {
   1852   CellDelayed<int> celld;
   1853   CellDelayed<int> celld2;
   1854   celld.foo();
   1855   celld.mu_.Lock();
   1856   celld2.mu_.Lock();
   1857 
   1858   celld.fooEx(&celld2);
   1859   celld.fooExT(&celld2);
   1860 
   1861   celld2.mu_.Unlock();
   1862   celld.mu_.Unlock();
   1863 }
   1864 
   1865 };  // end namespace TestTemplateAttributeInstantiation
   1866 
   1867 
   1868 namespace FunctionDeclDefTest {
   1869 
   1870 class Foo {
   1871 public:
   1872   Mutex mu_;
   1873   int a GUARDED_BY(mu_);
   1874 
   1875   virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
   1876 };
   1877 
   1878 // EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
   1879 void Foo::foo1(Foo *f_defined) {
   1880   f_defined->a = 0;
   1881 };
   1882 
   1883 void test() {
   1884   Foo myfoo;
   1885   myfoo.foo1(&myfoo);  // \
   1886     // expected-warning {{calling function 'foo1' requires exclusive lock on 'mu_'}}
   1887   myfoo.mu_.Lock();
   1888   myfoo.foo1(&myfoo);
   1889   myfoo.mu_.Unlock();
   1890 }
   1891 
   1892 };
   1893 
   1894 namespace GoingNative {
   1895 
   1896   struct __attribute__((lockable)) mutex {
   1897     void lock() __attribute__((exclusive_lock_function));
   1898     void unlock() __attribute__((unlock_function));
   1899     // ...
   1900   };
   1901   bool foo();
   1902   bool bar();
   1903   mutex m;
   1904   void test() {
   1905     m.lock();
   1906     while (foo()) {
   1907       m.unlock();
   1908       // ...
   1909       if (bar()) {
   1910         // ...
   1911         if (foo())
   1912           continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
   1913         //...
   1914       }
   1915       // ...
   1916       m.lock(); // expected-note {{mutex acquired here}}
   1917     }
   1918     m.unlock();
   1919   }
   1920 
   1921 }
   1922 
   1923 
   1924 
   1925 namespace FunctionDefinitionTest {
   1926 
   1927 class Foo {
   1928 public:
   1929   void foo1();
   1930   void foo2();
   1931   void foo3(Foo *other);
   1932 
   1933   template<class T>
   1934   void fooT1(const T& dummy1);
   1935 
   1936   template<class T>
   1937   void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
   1938 
   1939   Mutex mu_;
   1940   int a GUARDED_BY(mu_);
   1941 };
   1942 
   1943 template<class T>
   1944 class FooT {
   1945 public:
   1946   void foo();
   1947 
   1948   Mutex mu_;
   1949   T a GUARDED_BY(mu_);
   1950 };
   1951 
   1952 
   1953 void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
   1954   a = 1;
   1955 }
   1956 
   1957 void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
   1958   a = 2;
   1959 }
   1960 
   1961 void Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
   1962   other->a = 3;
   1963 }
   1964 
   1965 template<class T>
   1966 void Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
   1967   a = dummy1;
   1968 }
   1969 
   1970 /* TODO -- uncomment with template instantiation of attributes.
   1971 template<class T>
   1972 void Foo::fooT2(const T& dummy2) {
   1973   a = dummy2;
   1974 }
   1975 */
   1976 
   1977 void fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
   1978   f->a = 1;
   1979 }
   1980 
   1981 void fooF2(Foo *f);
   1982 void fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
   1983   f->a = 2;
   1984 }
   1985 
   1986 void fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
   1987 void fooF3(Foo *f) {
   1988   f->a = 3;
   1989 }
   1990 
   1991 template<class T>
   1992 void FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
   1993   a = 0;
   1994 }
   1995 
   1996 void test() {
   1997   int dummy = 0;
   1998   Foo myFoo;
   1999 
   2000   myFoo.foo2();        // \
   2001     // expected-warning {{calling function 'foo2' requires exclusive lock on 'mu_'}}
   2002   myFoo.foo3(&myFoo);  // \
   2003     // expected-warning {{calling function 'foo3' requires exclusive lock on 'mu_'}}
   2004   myFoo.fooT1(dummy);  // \
   2005     // expected-warning {{calling function 'fooT1' requires exclusive lock on 'mu_'}}
   2006 
   2007   // FIXME: uncomment with template instantiation of attributes patch
   2008   // myFoo.fooT2(dummy);  // expected warning
   2009 
   2010   fooF1(&myFoo);  // \
   2011     // expected-warning {{calling function 'fooF1' requires exclusive lock on 'mu_'}}
   2012   fooF2(&myFoo);  // \
   2013     // expected-warning {{calling function 'fooF2' requires exclusive lock on 'mu_'}}
   2014   fooF3(&myFoo);  // \
   2015     // expected-warning {{calling function 'fooF3' requires exclusive lock on 'mu_'}}
   2016 
   2017   myFoo.mu_.Lock();
   2018   myFoo.foo2();
   2019   myFoo.foo3(&myFoo);
   2020   myFoo.fooT1(dummy);
   2021 
   2022   // FIXME: uncomment with template instantiation of attributes patch
   2023   // myFoo.fooT2(dummy);
   2024 
   2025   fooF1(&myFoo);
   2026   fooF2(&myFoo);
   2027   fooF3(&myFoo);
   2028   myFoo.mu_.Unlock();
   2029 
   2030   FooT<int> myFooT;
   2031   myFooT.foo();  // \
   2032     // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
   2033 }
   2034 
   2035 } // end namespace FunctionDefinitionTest
   2036 
   2037 
   2038 namespace SelfLockingTest {
   2039 
   2040 class LOCKABLE MyLock {
   2041 public:
   2042   int foo GUARDED_BY(this);
   2043 
   2044   void lock()   EXCLUSIVE_LOCK_FUNCTION();
   2045   void unlock() UNLOCK_FUNCTION();
   2046 
   2047   void doSomething() {
   2048     this->lock();  // allow 'this' as a lock expression
   2049     foo = 0;
   2050     doSomethingElse();
   2051     this->unlock();
   2052   }
   2053 
   2054   void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
   2055     foo = 1;
   2056   };
   2057 
   2058   void test() {
   2059     foo = 2;  // \
   2060       // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
   2061   }
   2062 };
   2063 
   2064 
   2065 class LOCKABLE MyLock2 {
   2066 public:
   2067   Mutex mu_;
   2068   int foo GUARDED_BY(this);
   2069 
   2070   // don't check inside lock and unlock functions
   2071   void lock()   EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock();   }
   2072   void unlock() UNLOCK_FUNCTION()         { mu_.Unlock(); }
   2073 
   2074   // don't check inside constructors and destructors
   2075   MyLock2()  { foo = 1; }
   2076   ~MyLock2() { foo = 0; }
   2077 };
   2078 
   2079 
   2080 } // end namespace SelfLockingTest
   2081 
   2082 
   2083 namespace InvalidNonstatic {
   2084 
   2085 // Forward decl here causes bogus "invalid use of non-static data member"
   2086 // on reference to mutex_ in guarded_by attribute.
   2087 class Foo;
   2088 
   2089 class Foo {
   2090   Mutex* mutex_;
   2091 
   2092   int foo __attribute__((guarded_by(mutex_)));
   2093 };
   2094 
   2095 }  // end namespace InvalidNonStatic
   2096 
   2097 
   2098 namespace NoReturnTest {
   2099 
   2100 bool condition();
   2101 void fatal() __attribute__((noreturn));
   2102 
   2103 Mutex mu_;
   2104 
   2105 void test1() {
   2106   MutexLock lock(&mu_);
   2107   if (condition()) {
   2108     fatal();
   2109     return;
   2110   }
   2111 }
   2112 
   2113 } // end namespace NoReturnTest
   2114 
   2115 
   2116 namespace TestMultiDecl {
   2117 
   2118 class Foo {
   2119 public:
   2120   int GUARDED_BY(mu_) a;
   2121   int GUARDED_BY(mu_) b, c;
   2122 
   2123   void foo() {
   2124     a = 0; // \
   2125       // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
   2126     b = 0; // \
   2127       // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
   2128     c = 0; // \
   2129       // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
   2130   }
   2131 
   2132 private:
   2133   Mutex mu_;
   2134 };
   2135 
   2136 } // end namespace TestMultiDecl
   2137 
   2138 
   2139 namespace WarnNoDecl {
   2140 
   2141 class Foo {
   2142   void foo(int a);  __attribute__(( // \
   2143     // expected-warning {{declaration does not declare anything}}
   2144     exclusive_locks_required(a))); // \
   2145     // expected-warning {{attribute exclusive_locks_required ignored}}
   2146 };
   2147 
   2148 } // end namespace WarnNoDecl
   2149 
   2150 
   2151 
   2152 namespace MoreLockExpressions {
   2153 
   2154 class Foo {
   2155 public:
   2156   Mutex mu_;
   2157   int a GUARDED_BY(mu_);
   2158 };
   2159 
   2160 class Bar {
   2161 public:
   2162   int b;
   2163   Foo* f;
   2164 
   2165   Foo& getFoo()              { return *f; }
   2166   Foo& getFoo2(int c)        { return *f; }
   2167   Foo& getFoo3(int c, int d) { return *f; }
   2168 
   2169   Foo& getFooey() { return *f; }
   2170 };
   2171 
   2172 Foo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
   2173 
   2174 void test() {
   2175   Foo foo;
   2176   Foo *fooArray;
   2177   Bar bar;
   2178   int a;
   2179   int b;
   2180   int c;
   2181 
   2182   bar.getFoo().mu_.Lock();
   2183   bar.getFoo().a = 0;
   2184   bar.getFoo().mu_.Unlock();
   2185 
   2186   (bar.getFoo().mu_).Lock();   // test parenthesis
   2187   bar.getFoo().a = 0;
   2188   (bar.getFoo().mu_).Unlock();
   2189 
   2190   bar.getFoo2(a).mu_.Lock();
   2191   bar.getFoo2(a).a = 0;
   2192   bar.getFoo2(a).mu_.Unlock();
   2193 
   2194   bar.getFoo3(a, b).mu_.Lock();
   2195   bar.getFoo3(a, b).a = 0;
   2196   bar.getFoo3(a, b).mu_.Unlock();
   2197 
   2198   getBarFoo(bar, a).mu_.Lock();
   2199   getBarFoo(bar, a).a = 0;
   2200   getBarFoo(bar, a).mu_.Unlock();
   2201 
   2202   bar.getFoo2(10).mu_.Lock();
   2203   bar.getFoo2(10).a = 0;
   2204   bar.getFoo2(10).mu_.Unlock();
   2205 
   2206   bar.getFoo2(a + 1).mu_.Lock();
   2207   bar.getFoo2(a + 1).a = 0;
   2208   bar.getFoo2(a + 1).mu_.Unlock();
   2209 
   2210   (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
   2211   (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
   2212   (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
   2213 
   2214   bar.getFoo().mu_.Lock();
   2215   bar.getFooey().a = 0; // \
   2216     // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
   2217   bar.getFoo().mu_.Unlock();
   2218 
   2219   bar.getFoo2(a).mu_.Lock();
   2220   bar.getFoo2(b).a = 0; // \
   2221     // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
   2222   bar.getFoo2(a).mu_.Unlock();
   2223 
   2224   bar.getFoo3(a, b).mu_.Lock();
   2225   bar.getFoo3(a, c).a = 0;  // \
   2226     // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
   2227   bar.getFoo3(a, b).mu_.Unlock();
   2228 
   2229   getBarFoo(bar, a).mu_.Lock();
   2230   getBarFoo(bar, b).a = 0;  // \
   2231     // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
   2232   getBarFoo(bar, a).mu_.Unlock();
   2233 
   2234   (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
   2235   (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
   2236     // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
   2237   (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
   2238 }
   2239 
   2240 
   2241 } // end namespace
   2242 
   2243 
   2244