//===--- 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/Analysis/PathSensitive/CheckerVisitor.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/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));  
}
