summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/ThreadSafety.cpp
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2012-07-10 21:47:55 +0000
committerDeLesley Hutchins <delesley@google.com>2012-07-10 21:47:55 +0000
commit868830f727accb3a886b446c341e5370a8799690 (patch)
tree86434ecf204a30d6c7f5039dec826744c67c71fa /clang/lib/Analysis/ThreadSafety.cpp
parent67055f5ddce5b2120245cd153ffa4c795f76c129 (diff)
downloadbcm5719-llvm-868830f727accb3a886b446c341e5370a8799690.tar.gz
bcm5719-llvm-868830f727accb3a886b446c341e5370a8799690.zip
Thread safety analysis: impove handling of trylock expressions.
llvm-svn: 160018
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp41
1 files changed, 40 insertions, 1 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index a912aa97962..5bf3f8c65a1 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -1109,6 +1109,23 @@ void ThreadSafetyAnalyzer::getMutexIDs(MutexIDList &Mtxs, AttrType *Attr,
}
+bool getStaticBooleanValue(Expr* E, bool& TCond) {
+ if (isa<CXXNullPtrLiteralExpr>(E) || isa<GNUNullExpr>(E)) {
+ TCond = false;
+ return true;
+ } else if (CXXBoolLiteralExpr *BLE = dyn_cast<CXXBoolLiteralExpr>(E)) {
+ TCond = BLE->getValue();
+ return true;
+ } else if (IntegerLiteral *ILE = dyn_cast<IntegerLiteral>(E)) {
+ TCond = ILE->getValue().getBoolValue();
+ return true;
+ } else if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) {
+ return getStaticBooleanValue(CE->getSubExpr(), TCond);
+ }
+ return false;
+}
+
+
// If Cond can be traced back to a function call, return the call expression.
// The negate variable should be called with false, and will be set to true
// if the function call is negated, e.g. if (!mu.tryLock(...))
@@ -1121,6 +1138,9 @@ const CallExpr* ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond,
if (const CallExpr *CallExp = dyn_cast<CallExpr>(Cond)) {
return CallExp;
}
+ else if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond)) {
+ return getTrylockCallExpr(PE->getSubExpr(), C, Negate);
+ }
else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Cond)) {
return getTrylockCallExpr(CE->getSubExpr(), C, Negate);
}
@@ -1133,9 +1153,28 @@ const CallExpr* ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond,
Negate = !Negate;
return getTrylockCallExpr(UOP->getSubExpr(), C, Negate);
}
+ return 0;
+ }
+ else if (const BinaryOperator *BOP = dyn_cast<BinaryOperator>(Cond)) {
+ if (BOP->getOpcode() == BO_EQ || BOP->getOpcode() == BO_NE) {
+ if (BOP->getOpcode() == BO_NE)
+ Negate = !Negate;
+
+ bool TCond = false;
+ if (getStaticBooleanValue(BOP->getRHS(), TCond)) {
+ if (!TCond) Negate = !Negate;
+ return getTrylockCallExpr(BOP->getLHS(), C, Negate);
+ }
+ else if (getStaticBooleanValue(BOP->getLHS(), TCond)) {
+ if (!TCond) Negate = !Negate;
+ return getTrylockCallExpr(BOP->getRHS(), C, Negate);
+ }
+ return 0;
+ }
+ return 0;
}
// FIXME -- handle && and || as well.
- return NULL;
+ return 0;
}
OpenPOWER on IntegriCloud