//===-- BlockInCriticalSectionChecker.cpp -----------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Defines a checker for blocks in critical sections. This checker should find
// the calls to blocking functions (for example: sleep, getc, fgets, read,
// recv etc.) inside a critical section. When sleep(x) is called while a mutex
// is held, other threades cannot lock the same mutex. This might take some
// time, leading to bad performance or even deadlock.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"

using namespace clang;
using namespace ento;

namespace {

class BlockInCriticalSectionChecker : public Checker<check::PostCall> {

  mutable IdentifierInfo *IILockGuard, *IIUniqueLock;

  CallDescription LockFn, UnlockFn, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn,
                  PthreadLockFn, PthreadTryLockFn, PthreadUnlockFn,
                  MtxLock, MtxTimedLock, MtxTryLock, MtxUnlock;

  StringRef ClassLockGuard, ClassUniqueLock;

  mutable bool IdentifierInfoInitialized;

  std::unique_ptr<BugType> BlockInCritSectionBugType;

  void initIdentifierInfo(ASTContext &Ctx) const;

  void reportBlockInCritSection(SymbolRef FileDescSym,
                                const CallEvent &call,
                                CheckerContext &C) const;

public:
  BlockInCriticalSectionChecker();

  bool isBlockingFunction(const CallEvent &Call) const;
  bool isLockFunction(const CallEvent &Call) const;
  bool isUnlockFunction(const CallEvent &Call) const;

  /// Process unlock.
  /// Process lock.
  /// Process blocking functions (sleep, getc, fgets, read, recv)
  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
};

} // end anonymous namespace

REGISTER_TRAIT_WITH_PROGRAMSTATE(MutexCounter, unsigned)

BlockInCriticalSectionChecker::BlockInCriticalSectionChecker()
    : IILockGuard(nullptr), IIUniqueLock(nullptr),
      LockFn("lock"), UnlockFn("unlock"), SleepFn("sleep"), GetcFn("getc"),
      FgetsFn("fgets"), ReadFn("read"), RecvFn("recv"),
      PthreadLockFn("pthread_mutex_lock"),
      PthreadTryLockFn("pthread_mutex_trylock"),
      PthreadUnlockFn("pthread_mutex_unlock"),
      MtxLock("mtx_lock"),
      MtxTimedLock("mtx_timedlock"),
      MtxTryLock("mtx_trylock"),
      MtxUnlock("mtx_unlock"),
      ClassLockGuard("lock_guard"),
      ClassUniqueLock("unique_lock"),
      IdentifierInfoInitialized(false) {
  // Initialize the bug type.
  BlockInCritSectionBugType.reset(
      new BugType(this, "Call to blocking function in critical section",
                        "Blocking Error"));
}

void BlockInCriticalSectionChecker::initIdentifierInfo(ASTContext &Ctx) const {
  if (!IdentifierInfoInitialized) {
    /* In case of checking C code, or when the corresponding headers are not
     * included, we might end up query the identifier table every time when this
     * function is called instead of early returning it. To avoid this, a bool
     * variable (IdentifierInfoInitialized) is used and the function will be run
     * only once. */
    IILockGuard  = &Ctx.Idents.get(ClassLockGuard);
    IIUniqueLock = &Ctx.Idents.get(ClassUniqueLock);
    IdentifierInfoInitialized = true;
  }
}

bool BlockInCriticalSectionChecker::isBlockingFunction(const CallEvent &Call) const {
  if (Call.isCalled(SleepFn)
      || Call.isCalled(GetcFn)
      || Call.isCalled(FgetsFn)
      || Call.isCalled(ReadFn)
      || Call.isCalled(RecvFn)) {
    return true;
  }
  return false;
}

bool BlockInCriticalSectionChecker::isLockFunction(const CallEvent &Call) const {
  if (const auto *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
    auto IdentifierInfo = Ctor->getDecl()->getParent()->getIdentifier();
    if (IdentifierInfo == IILockGuard || IdentifierInfo == IIUniqueLock)
      return true;
  }

  if (Call.isCalled(LockFn)
      || Call.isCalled(PthreadLockFn)
      || Call.isCalled(PthreadTryLockFn)
      || Call.isCalled(MtxLock)
      || Call.isCalled(MtxTimedLock)
      || Call.isCalled(MtxTryLock)) {
    return true;
  }
  return false;
}

bool BlockInCriticalSectionChecker::isUnlockFunction(const CallEvent &Call) const {
  if (const auto *Dtor = dyn_cast<CXXDestructorCall>(&Call)) {
    const auto *DRecordDecl = cast<CXXRecordDecl>(Dtor->getDecl()->getParent());
    auto IdentifierInfo = DRecordDecl->getIdentifier();
    if (IdentifierInfo == IILockGuard || IdentifierInfo == IIUniqueLock)
      return true;
  }

  if (Call.isCalled(UnlockFn)
       || Call.isCalled(PthreadUnlockFn)
       || Call.isCalled(MtxUnlock)) {
    return true;
  }
  return false;
}

void BlockInCriticalSectionChecker::checkPostCall(const CallEvent &Call,
                                                  CheckerContext &C) const {
  initIdentifierInfo(C.getASTContext());

  if (!isBlockingFunction(Call)
      && !isLockFunction(Call)
      && !isUnlockFunction(Call))
    return;

  ProgramStateRef State = C.getState();
  unsigned mutexCount = State->get<MutexCounter>();
  if (isUnlockFunction(Call) && mutexCount > 0) {
    State = State->set<MutexCounter>(--mutexCount);
    C.addTransition(State);
  } else if (isLockFunction(Call)) {
    State = State->set<MutexCounter>(++mutexCount);
    C.addTransition(State);
  } else if (mutexCount > 0) {
    SymbolRef BlockDesc = Call.getReturnValue().getAsSymbol();
    reportBlockInCritSection(BlockDesc, Call, C);
  }
}

void BlockInCriticalSectionChecker::reportBlockInCritSection(
    SymbolRef BlockDescSym, const CallEvent &Call, CheckerContext &C) const {
  ExplodedNode *ErrNode = C.generateNonFatalErrorNode();
  if (!ErrNode)
    return;

  std::string msg;
  llvm::raw_string_ostream os(msg);
  os << "Call to blocking function '" << Call.getCalleeIdentifier()->getName()
     << "' inside of critical section";
  auto R = std::make_unique<PathSensitiveBugReport>(*BlockInCritSectionBugType,
                                                    os.str(), ErrNode);
  R->addRange(Call.getSourceRange());
  R->markInteresting(BlockDescSym);
  C.emitReport(std::move(R));
}

void ento::registerBlockInCriticalSectionChecker(CheckerManager &mgr) {
  mgr.registerChecker<BlockInCriticalSectionChecker>();
}

bool ento::shouldRegisterBlockInCriticalSectionChecker(const LangOptions &LO) {
  return true;
}
