diff options
author | DeLesley Hutchins <delesley@google.com> | 2012-07-10 21:47:55 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2012-07-10 21:47:55 +0000 |
commit | 13106117060c90d6f84bd2ed7a5c03e0502ff419 (patch) | |
tree | a35f0797a11c6edd70174adfe0bd21604ed42d6b /lib/Analysis/ThreadSafety.cpp | |
parent | b660446bcf47bfbcdebaf65a6616c4046579987a (diff) |
Thread safety analysis: impove handling of trylock expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160018 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ThreadSafety.cpp')
-rw-r--r-- | lib/Analysis/ThreadSafety.cpp | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp index a912aa9796..5bf3f8c65a 100644 --- a/lib/Analysis/ThreadSafety.cpp +++ b/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; } |