blob: 6c76b397e9bece8eafdb8ff3e313cbc49d3bc975 [file] [log] [blame]
// Test lock/trylock/unlock annotations with unsupported or unrecognized lock
// names/expressions
// { dg-do compile }
// { dg-options "-Wthread-safety -Wthread-unsupported-lock-name -O" }
#include "thread_annot_common.h"
namespace ns1 {
template <typename T>
class Bar {
public:
void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
void Unlock() UNLOCK_FUNCTION(mu_);
void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1); // { dg-warning "Unsupported argument of 'exclusive_lock' attribute ignored" }
void MyUnlock() UNLOCK_FUNCTION(mu1); // { dg-warning "Unsupported argument of 'unlock' attribute ignored" }
T get_foo() {
T ret;
MyLock();
ret = foo;
MyUnlock();
return ret;
}
void set_foo(T a) {
Lock();
foo = a;
Unlock();
}
private:
Mutex mu_;
T foo GUARDED_BY(mu_);
};
int pthread_mutex_lock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu)
{
return 5;
}
int pthread_mutex_unlock(Mutex *mu) UNLOCK_FUNCTION(mu);
int pthread_mutex_trylock() EXCLUSIVE_TRYLOCK_FUNCTION(0, (t->mu1)); // { dg-warning "Unsupported argument of 'exclusive_trylock' attribute ignored" }
Mutex mu2;
int p GUARDED_BY(mu2);
int r;
Bar<float> *b1;
void func1()
{
b1->set_foo(3.5);
pthread_mutex_lock(&mu2);
r = b1->get_foo();
p = r + 5;
pthread_mutex_unlock(&mu2);
if (!pthread_mutex_trylock())
{
p = 2;
// Since the annotation on pthread_mutex_trylock contains an unrecognized
// lock (t->mu1), we don't warn if it is not released at the end of the
// scope.
}
pthread_mutex_lock(&mu2);
// Since the annotation on Bar<float>::MyUnlock contains an unrecognized
// lock name, the analysis would conservatively disable the check for
// mismatched lock acquire/release. Therefore even though mu2 is not
// released, we don't emit a warning.
b1->MyUnlock();
}
}