blob: 246eabe0ca18d5154c6f01a61152ce9470ca00af [file] [log] [blame]
// Test the support for users to specify in the annotations a lock that is a
// class/struct member of a function parameter in templates.
// { dg-do compile }
// { dg-options "-Wthread-safety -O" }
#include "thread_annot_common.h"
class Foo {
public:
Mutex *mu1_;
int data_ GUARDED_BY(mu1_);
};
template<typename T>
class Bar {
public:
T *foo_;
void MyLock(T *f) EXCLUSIVE_LOCK_FUNCTION(f->mu1_);
void MyUnlock(T *f) UNLOCK_FUNCTION(f->mu1_);
void func2(T *f) SHARED_LOCKS_REQUIRED(f->mu1_);
void func3();
};
class SCOPED_LOCKABLE MyMutexLock {
public:
MyMutexLock(Foo *f) EXCLUSIVE_LOCK_FUNCTION(f->mu1_)
: mu_(f->mu1_) {
this->mu_->Lock();
}
~MyMutexLock() UNLOCK_FUNCTION(){ this->mu_->Unlock(); }
private:
Mutex *const mu_;
};
Mutex *mu2;
void func1(Bar<Foo> *bar, Mutex *mu)
EXCLUSIVE_LOCKS_REQUIRED(bar->foo_->mu1_, mu) {
bar->foo_->data_ = 5;
}
template<typename T>
void Bar<T>::func3() {
func2(foo_); // { dg-warning "Calling function 'func2' requires lock" }
}
main() {
Bar<Foo> *b;
MutexLock l(mu2);
func1(b, mu2); // { dg-warning "Calling function 'func1' requires lock" }
b->func3();
func1(b, mu2); // { dg-warning "Calling function 'func1' requires lock" }
}