// SmartPtrChecker.cpp - Check for smart pointer dereference - 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
//
//===----------------------------------------------------------------------===//
//
// This file defines a checker that check for null dereference of C++ smart
// pointer.
//
//===----------------------------------------------------------------------===//
#include "SmartPtr.h"

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

using namespace clang;
using namespace ento;

namespace {

static const BugType *NullDereferenceBugTypePtr;

class SmartPtrChecker : public Checker<check::PreCall> {
public:
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
  BugType NullDereferenceBugType{this, "Null SmartPtr dereference",
                                 "C++ Smart Pointer"};

private:
  void reportBug(CheckerContext &C, const MemRegion *DerefRegion,
                 const CallEvent &Call) const;
  void explainDereference(llvm::raw_ostream &OS, const MemRegion *DerefRegion,
                          const CallEvent &Call) const;
};
} // end of anonymous namespace

// Define the inter-checker API.
namespace clang {
namespace ento {
namespace smartptr {

const BugType *getNullDereferenceBugType() { return NullDereferenceBugTypePtr; }

} // namespace smartptr
} // namespace ento
} // namespace clang

void SmartPtrChecker::checkPreCall(const CallEvent &Call,
                                   CheckerContext &C) const {
  if (!smartptr::isStdSmartPtrCall(Call))
    return;
  ProgramStateRef State = C.getState();
  const auto *OC = dyn_cast<CXXMemberOperatorCall>(&Call);
  if (!OC)
    return;
  const MemRegion *ThisRegion = OC->getCXXThisVal().getAsRegion();
  if (!ThisRegion)
    return;

  OverloadedOperatorKind OOK = OC->getOverloadedOperator();
  if (OOK == OO_Star || OOK == OO_Arrow) {
    if (smartptr::isNullSmartPtr(State, ThisRegion))
      reportBug(C, ThisRegion, Call);
  }
}

void SmartPtrChecker::reportBug(CheckerContext &C, const MemRegion *DerefRegion,
                                const CallEvent &Call) const {
  ExplodedNode *ErrNode = C.generateErrorNode();
  if (!ErrNode)
    return;
  llvm::SmallString<128> Str;
  llvm::raw_svector_ostream OS(Str);
  explainDereference(OS, DerefRegion, Call);
  auto R = std::make_unique<PathSensitiveBugReport>(NullDereferenceBugType,
                                                    OS.str(), ErrNode);
  R->markInteresting(DerefRegion);
  C.emitReport(std::move(R));
}

void SmartPtrChecker::explainDereference(llvm::raw_ostream &OS,
                                         const MemRegion *DerefRegion,
                                         const CallEvent &Call) const {
  OS << "Dereference of null smart pointer ";
  DerefRegion->printPretty(OS);
}

void ento::registerSmartPtrChecker(CheckerManager &Mgr) {
  SmartPtrChecker *Checker = Mgr.registerChecker<SmartPtrChecker>();
  NullDereferenceBugTypePtr = &Checker->NullDereferenceBugType;
}

bool ento::shouldRegisterSmartPtrChecker(const CheckerManager &mgr) {
  const LangOptions &LO = mgr.getLangOpts();
  return LO.CPlusPlus;
}
