1// Copyright 2018 The Chromium Authors 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// This is a "No Compile Test" suite. 6// https://dev.chromium.org/developers/testing/no-compile-tests 7 8#include "base/thread_annotations.h" 9 10namespace { 11 12class LOCKABLE Lock { 13 public: 14 void Acquire() EXCLUSIVE_LOCK_FUNCTION() {} 15 void Release() UNLOCK_FUNCTION() {} 16}; 17 18class SCOPED_LOCKABLE AutoLock { 19 public: 20 AutoLock(Lock& lock) EXCLUSIVE_LOCK_FUNCTION(lock) : lock_(lock) { 21 lock.Acquire(); 22 } 23 ~AutoLock() UNLOCK_FUNCTION() { lock_.Release(); } 24 25 private: 26 Lock& lock_; 27}; 28 29class ThreadSafe { 30 public: 31 void IncrementWithoutRelease(); 32 void IncrementWithoutAcquire(); 33 void IncrementWithWronglyScopedLock(); 34 private: 35 Lock lock_; 36 int counter_ GUARDED_BY(lock_); 37}; 38 39void ThreadSafe::IncrementWithoutRelease() { 40 lock_.Acquire(); 41 ++counter_; 42 // Forgot to release the lock. 43} // expected-error {{mutex 'lock_' is still held at the end of function}} 44 45void ThreadSafe::IncrementWithoutAcquire() { 46 // Member access without holding the lock guarding it. 47 ++counter_; // expected-error {{writing variable 'counter_' requires holding mutex 'lock_' exclusively}} 48} 49 50void ThreadSafe::IncrementWithWronglyScopedLock() { 51 { 52 AutoLock auto_lock(lock_); 53 // The AutoLock will go out of scope before the guarded member access. 54 } 55 ++counter_; // expected-error {{writing variable 'counter_' requires holding mutex 'lock_' exclusively}} 56} 57 58int not_lockable; 59int global_counter GUARDED_BY(not_lockable); // expected-error {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute}} 60 61} // anonymous namespace 62