1// Copyright 2018 The Chromium Authors. All rights reserved. 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}; 28class ThreadSafe { 29 public: 30 void BuggyIncrement(); 31 private: 32 Lock lock_; 33 int counter_ GUARDED_BY(lock_); 34}; 35 36#if defined(NCTEST_LOCK_WITHOUT_UNLOCK) // [r"fatal error: mutex 'lock_' is still held at the end of function"] 37 38void ThreadSafe::BuggyIncrement() { 39 lock_.Acquire(); 40 ++counter_; 41 // Forgot to release the lock. 42} 43 44#elif defined(NCTEST_ACCESS_WITHOUT_LOCK) // [r"fatal error: writing variable 'counter_' requires holding mutex 'lock_' exclusively"] 45 46void ThreadSafe::BuggyIncrement() { 47 // Member access without holding the lock guarding it. 48 ++counter_; 49} 50 51#elif defined(NCTEST_ACCESS_WITHOUT_SCOPED_LOCK) // [r"fatal error: writing variable 'counter_' requires holding mutex 'lock_' exclusively"] 52 53void ThreadSafe::BuggyIncrement() { 54 { 55 AutoLock auto_lock(lock_); 56 // The AutoLock will go out of scope before the guarded member access. 57 } 58 ++counter_; 59} 60 61#elif defined(NCTEST_GUARDED_BY_WRONG_TYPE) // [r"fatal error: 'guarded_by' attribute requires arguments whose type is annotated"] 62 63int not_lockable; 64int global_counter GUARDED_BY(not_lockable); 65 66// Defined to avoid link error. 67void ThreadSafe::BuggyIncrement() { } 68 69#endif 70 71} // anonymous namespace 72