forked from OSchip/llvm-project
Thread safety analysis: Unwrap __builtin_expect in getTrylockCallExpr
Summary: When people are really sure they'll get the lock they sometimes use __builtin_expect. It's also used by some assertion implementations. Asserting that try-lock succeeded is basically the same as asserting that the lock is not held by anyone else (and acquiring it). Reviewers: aaron.ballman, delesley Reviewed By: aaron.ballman Subscribers: kristina, cfe-commits Differential Revision: https://reviews.llvm.org/D52398 llvm-svn: 343681
This commit is contained in:
parent
d5a39553ff
commit
7146b0032f
|
@ -33,6 +33,7 @@
|
|||
#include "clang/Analysis/Analyses/ThreadSafetyUtil.h"
|
||||
#include "clang/Analysis/AnalysisDeclContext.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/OperatorKinds.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
|
@ -1388,8 +1389,11 @@ const CallExpr* ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond,
|
|||
if (!Cond)
|
||||
return nullptr;
|
||||
|
||||
if (const auto *CallExp = dyn_cast<CallExpr>(Cond))
|
||||
if (const auto *CallExp = dyn_cast<CallExpr>(Cond)) {
|
||||
if (CallExp->getBuiltinCallee() == Builtin::BI__builtin_expect)
|
||||
return getTrylockCallExpr(CallExp->getArg(0), C, Negate);
|
||||
return CallExp;
|
||||
}
|
||||
else if (const auto *PE = dyn_cast<ParenExpr>(Cond))
|
||||
return getTrylockCallExpr(PE->getSubExpr(), C, Negate);
|
||||
else if (const auto *CE = dyn_cast<ImplicitCastExpr>(Cond))
|
||||
|
|
|
@ -1754,6 +1754,13 @@ struct TestTryLock {
|
|||
mu.Unlock();
|
||||
}
|
||||
|
||||
void foo2_builtin_expect() {
|
||||
if (__builtin_expect(!mu.TryLock(), false))
|
||||
return;
|
||||
a = 2;
|
||||
mu.Unlock();
|
||||
}
|
||||
|
||||
void foo3() {
|
||||
bool b = mu.TryLock();
|
||||
if (b) {
|
||||
|
@ -1762,6 +1769,14 @@ struct TestTryLock {
|
|||
}
|
||||
}
|
||||
|
||||
void foo3_builtin_expect() {
|
||||
bool b = mu.TryLock();
|
||||
if (__builtin_expect(b, true)) {
|
||||
a = 3;
|
||||
mu.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void foo4() {
|
||||
bool b = mu.TryLock();
|
||||
if (!b) return;
|
||||
|
|
Loading…
Reference in New Issue