aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/ThreadSafety.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp82
1 files changed, 46 insertions, 36 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index e25b843..550c2a3 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -37,6 +37,7 @@
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ImmutableMap.h"
@@ -1034,9 +1035,10 @@ public:
template <class AttrType>
void getMutexIDs(CapExprSet &Mtxs, AttrType *Attr, const Expr *Exp,
- const NamedDecl *D,
- const CFGBlock *PredBlock, const CFGBlock *CurrBlock,
- Expr *BrE, bool Neg);
+ const NamedDecl *D, const CFGBlock *PredBlock,
+ const CFGBlock *CurrBlock,
+ const ASTContext &TrylockAttrContext,
+ Expr *TrylockAttrSuccessValue, bool Neg);
const CallExpr* getTrylockCallExpr(const Stmt *Cond, LocalVarContext C,
bool &Negate);
@@ -1359,17 +1361,18 @@ void ThreadSafetyAnalyzer::getMutexIDs(CapExprSet &Mtxs, AttrType *Attr,
const Expr *Exp, const NamedDecl *D,
const CFGBlock *PredBlock,
const CFGBlock *CurrBlock,
- Expr *BrE, bool Neg) {
- // Find out which branch has the lock
- bool branch = false;
- if (const auto *BLE = dyn_cast_or_null<CXXBoolLiteralExpr>(BrE))
- branch = BLE->getValue();
- else if (const auto *ILE = dyn_cast_or_null<IntegerLiteral>(BrE))
- branch = ILE->getValue().getBoolValue();
-
- int branchnum = branch ? 0 : 1;
- if (Neg)
- branchnum = !branchnum;
+ const ASTContext &TrylockAttrContext,
+ Expr *TrylockAttrSuccess,
+ bool Neg) {
+ // Evaluate the trylock's success value as a boolean.
+ bool trylockSuccessValue = false;
+ if (!TrylockAttrSuccess->EvaluateAsBooleanCondition(
+ trylockSuccessValue, TrylockAttrContext,
+ /*InConstantContext=*/true)) {
+ llvm_unreachable("Trylock success value could not be evaluated.");
+ }
+
+ const int branchnum = Neg ? !!trylockSuccessValue : !trylockSuccessValue;
// If we've taken the trylock branch, then add the lock
int i = 0;
@@ -1390,8 +1393,15 @@ static bool getStaticBooleanValue(Expr *E, bool &TCond) {
} else if (const auto *ILE = dyn_cast<IntegerLiteral>(E)) {
TCond = ILE->getValue().getBoolValue();
return true;
- } else if (auto *CE = dyn_cast<ImplicitCastExpr>(E))
+ } else if (auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
return getStaticBooleanValue(CE->getSubExpr(), TCond);
+ } else if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
+ if (auto *ECD = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
+ llvm::APSInt IV = ECD->getInitVal();
+ TCond = IV.getBoolValue();
+ return true;
+ }
+ }
return false;
}
@@ -1497,27 +1507,27 @@ void ThreadSafetyAnalyzer::getEdgeLockset(FactSet& Result,
// If the condition is a call to a Trylock function, then grab the attributes
for (const auto *Attr : FunDecl->attrs()) {
switch (Attr->getKind()) {
- case attr::TryAcquireCapability: {
- auto *A = cast<TryAcquireCapabilityAttr>(Attr);
- getMutexIDs(A->isShared() ? SharedLocksToAdd : ExclusiveLocksToAdd, A,
- Exp, FunDecl, PredBlock, CurrBlock, A->getSuccessValue(),
- Negate);
- break;
- };
- case attr::ExclusiveTrylockFunction: {
- const auto *A = cast<ExclusiveTrylockFunctionAttr>(Attr);
- getMutexIDs(ExclusiveLocksToAdd, A, Exp, FunDecl, PredBlock, CurrBlock,
- A->getSuccessValue(), Negate);
- break;
- }
- case attr::SharedTrylockFunction: {
- const auto *A = cast<SharedTrylockFunctionAttr>(Attr);
- getMutexIDs(SharedLocksToAdd, A, Exp, FunDecl, PredBlock, CurrBlock,
- A->getSuccessValue(), Negate);
- break;
- }
- default:
- break;
+ case attr::TryAcquireCapability: {
+ auto *A = cast<TryAcquireCapabilityAttr>(Attr);
+ getMutexIDs(A->isShared() ? SharedLocksToAdd : ExclusiveLocksToAdd, A,
+ Exp, FunDecl, PredBlock, CurrBlock, FunDecl->getASTContext(),
+ A->getSuccessValue(), Negate);
+ break;
+ };
+ case attr::ExclusiveTrylockFunction: {
+ const auto *A = cast<ExclusiveTrylockFunctionAttr>(Attr);
+ getMutexIDs(ExclusiveLocksToAdd, A, Exp, FunDecl, PredBlock, CurrBlock,
+ FunDecl->getASTContext(), A->getSuccessValue(), Negate);
+ break;
+ }
+ case attr::SharedTrylockFunction: {
+ const auto *A = cast<SharedTrylockFunctionAttr>(Attr);
+ getMutexIDs(SharedLocksToAdd, A, Exp, FunDecl, PredBlock, CurrBlock,
+ FunDecl->getASTContext(), A->getSuccessValue(), Negate);
+ break;
+ }
+ default:
+ break;
}
}