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