зеркало из https://github.com/microsoft/clang-1.git
Thread-safety analysis: fix handling of LOCK_RETURNED attribute so that the
latest definition of a function is always used when computing lock expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163028 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
1999bd61da
Коммит
5408153e91
|
@ -300,8 +300,9 @@ private:
|
|||
} else if (CXXMemberCallExpr *CMCE = dyn_cast<CXXMemberCallExpr>(Exp)) {
|
||||
// When calling a function with a lock_returned attribute, replace
|
||||
// the function call with the expression in lock_returned.
|
||||
if (LockReturnedAttr* At =
|
||||
CMCE->getMethodDecl()->getAttr<LockReturnedAttr>()) {
|
||||
CXXMethodDecl* MD =
|
||||
cast<CXXMethodDecl>(CMCE->getMethodDecl()->getMostRecentDecl());
|
||||
if (LockReturnedAttr* At = MD->getAttr<LockReturnedAttr>()) {
|
||||
CallingContext LRCallCtx(CMCE->getMethodDecl());
|
||||
LRCallCtx.SelfArg = CMCE->getImplicitObjectArgument();
|
||||
LRCallCtx.SelfArrow =
|
||||
|
@ -330,8 +331,9 @@ private:
|
|||
NodeVec[Root].setSize(Sz + 1);
|
||||
return Sz + 1;
|
||||
} else if (CallExpr *CE = dyn_cast<CallExpr>(Exp)) {
|
||||
if (LockReturnedAttr* At =
|
||||
CE->getDirectCallee()->getAttr<LockReturnedAttr>()) {
|
||||
FunctionDecl* FD =
|
||||
cast<FunctionDecl>(CE->getDirectCallee()->getMostRecentDecl());
|
||||
if (LockReturnedAttr* At = FD->getAttr<LockReturnedAttr>()) {
|
||||
CallingContext LRCallCtx(CE->getDirectCallee());
|
||||
LRCallCtx.NumArgs = CE->getNumArgs();
|
||||
LRCallCtx.FunArgs = CE->getArgs();
|
||||
|
|
|
@ -3145,3 +3145,48 @@ public:
|
|||
} // end namespace StringIgnoreTest
|
||||
|
||||
|
||||
namespace LockReturnedScopeFix {
|
||||
|
||||
class Base {
|
||||
protected:
|
||||
struct Inner;
|
||||
bool c;
|
||||
|
||||
const Mutex& getLock(const Inner* i);
|
||||
|
||||
void lockInner (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
|
||||
void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
|
||||
void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
|
||||
|
||||
void bar(Inner* i);
|
||||
};
|
||||
|
||||
|
||||
struct Base::Inner {
|
||||
Mutex lock_;
|
||||
void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
|
||||
};
|
||||
|
||||
|
||||
const Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
|
||||
return i->lock_;
|
||||
}
|
||||
|
||||
|
||||
void Base::foo(Inner* i) {
|
||||
i->doSomething();
|
||||
}
|
||||
|
||||
void Base::bar(Inner* i) {
|
||||
if (c) {
|
||||
i->lock_.Lock();
|
||||
unlockInner(i);
|
||||
}
|
||||
else {
|
||||
lockInner(i);
|
||||
i->lock_.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace LockReturnedScopeFix
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче