summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Checker/PthreadLockChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Checker/PthreadLockChecker.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Checker/PthreadLockChecker.cpp141
1 files changed, 0 insertions, 141 deletions
diff --git a/contrib/llvm/tools/clang/lib/Checker/PthreadLockChecker.cpp b/contrib/llvm/tools/clang/lib/Checker/PthreadLockChecker.cpp
deleted file mode 100644
index 74e266c..0000000
--- a/contrib/llvm/tools/clang/lib/Checker/PthreadLockChecker.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-//===--- PthreadLockChecker.h - Undefined arguments checker ----*- C++ -*--===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This defines PthreadLockChecker, a simple lock -> unlock checker. Eventually
-// this shouldn't be registered with GRExprEngineInternalChecks.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Checker/PathSensitive/CheckerVisitor.h"
-#include "clang/Checker/BugReporter/BugReporter.h"
-#include "clang/Checker/PathSensitive/GRStateTrait.h"
-#include "GRExprEngineExperimentalChecks.h"
-#include "llvm/ADT/ImmutableSet.h"
-
-using namespace clang;
-
-namespace {
-class PthreadLockChecker
- : public CheckerVisitor<PthreadLockChecker> {
- BugType *BT;
-public:
- PthreadLockChecker() : BT(0) {}
- static void *getTag() {
- static int x = 0;
- return &x;
- }
- void PostVisitCallExpr(CheckerContext &C, const CallExpr *CE);
-
- void AcquireLock(CheckerContext &C, const CallExpr *CE,
- SVal lock, bool isTryLock);
-
- void ReleaseLock(CheckerContext &C, const CallExpr *CE,
- SVal lock);
-
-};
-} // end anonymous namespace
-
-// GDM Entry for tracking lock state.
-namespace { class LockSet {}; }
-namespace clang {
-template <> struct GRStateTrait<LockSet> :
- public GRStatePartialTrait<llvm::ImmutableSet<const MemRegion*> > {
- static void* GDMIndex() { return PthreadLockChecker::getTag(); }
-};
-} // end clang namespace
-
-void clang::RegisterPthreadLockChecker(GRExprEngine &Eng) {
- Eng.registerCheck(new PthreadLockChecker());
-}
-
-
-void PthreadLockChecker::PostVisitCallExpr(CheckerContext &C,
- const CallExpr *CE) {
- const GRState *state = C.getState();
- const Expr *Callee = CE->getCallee();
- const FunctionTextRegion *R =
- dyn_cast_or_null<FunctionTextRegion>(state->getSVal(Callee).getAsRegion());
-
- if (!R)
- return;
-
- llvm::StringRef FName = R->getDecl()->getName();
-
- if (FName == "pthread_mutex_lock") {
- if (CE->getNumArgs() != 1)
- return;
- AcquireLock(C, CE, state->getSVal(CE->getArg(0)), false);
- }
- else if (FName == "pthread_mutex_trylock") {
- if (CE->getNumArgs() != 1)
- return;
- AcquireLock(C, CE, state->getSVal(CE->getArg(0)), true);
- }
- else if (FName == "pthread_mutex_unlock") {
- if (CE->getNumArgs() != 1)
- return;
- ReleaseLock(C, CE, state->getSVal(CE->getArg(0)));
- }
-}
-
-void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
- SVal lock, bool isTryLock) {
-
- const MemRegion *lockR = lock.getAsRegion();
- if (!lockR)
- return;
-
- const GRState *state = C.getState();
-
- SVal X = state->getSVal(CE);
- if (X.isUnknownOrUndef())
- return;
-
- DefinedSVal retVal = cast<DefinedSVal>(X);
- const GRState *lockSucc = state;
-
- if (isTryLock) {
- // Bifurcate the state, and allow a mode where the lock acquisition fails.
- const GRState *lockFail;
- llvm::tie(lockFail, lockSucc) = state->Assume(retVal);
- assert(lockFail && lockSucc);
- C.addTransition(C.GenerateNode(CE, lockFail));
- }
- else {
- // Assume that the return value was 0.
- lockSucc = state->Assume(retVal, false);
- assert(lockSucc);
- }
-
- // Record that the lock was acquired.
- lockSucc = lockSucc->add<LockSet>(lockR);
-
- C.addTransition(lockSucc != state ? C.GenerateNode(CE, lockSucc) :
- C.getPredecessor());
-}
-
-void PthreadLockChecker::ReleaseLock(CheckerContext &C, const CallExpr *CE,
- SVal lock) {
-
- const MemRegion *lockR = lock.getAsRegion();
- if (!lockR)
- return;
-
- const GRState *state = C.getState();
-
- // Record that the lock was released.
- // FIXME: Handle unlocking locks that were never acquired. This may
- // require IPA for wrappers.
- const GRState *unlockState = state->remove<LockSet>(lockR);
-
- if (state == unlockState)
- return;
-
- C.addTransition(C.GenerateNode(CE, unlockState));
-}
OpenPOWER on IntegriCloud