//===- ObjCSuperDeallocChecker.cpp - Check correct use of [super dealloc] -===//
//
// 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 defines ObjCSuperDeallocChecker, a builtin check that warns when
// self is used after a call to [super dealloc] in MRR mode.
//
//===----------------------------------------------------------------------===//

#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"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"

using namespace clang;
using namespace ento;

namespace {
class ObjCSuperDeallocChecker
    : public Checker<check::PostObjCMessage, check::PreObjCMessage,
                     check::PreCall, check::Location> {
  mutable const IdentifierInfo *IIdealloc = nullptr;
  mutable const IdentifierInfo *IINSObject = nullptr;
  mutable Selector SELdealloc;

  const BugType DoubleSuperDeallocBugType{
      this, "[super dealloc] should not be called more than once",
      categories::CoreFoundationObjectiveC};

  void initIdentifierInfoAndSelectors(ASTContext &Ctx) const;

  bool isSuperDeallocMessage(const ObjCMethodCall &M) const;

public:
  void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
  void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;

  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;

  void checkLocation(SVal l, bool isLoad, const Stmt *S,
                     CheckerContext &C) const;

private:

  void diagnoseCallArguments(const CallEvent &CE, CheckerContext &C) const;

  void reportUseAfterDealloc(SymbolRef Sym, StringRef Desc, const Stmt *S,
                             CheckerContext &C) const;
};

} // End anonymous namespace.

// Remember whether [super dealloc] has previously been called on the
// SymbolRef for the receiver.
REGISTER_SET_WITH_PROGRAMSTATE(CalledSuperDealloc, SymbolRef)

namespace {
class SuperDeallocBRVisitor final : public BugReporterVisitor {
  SymbolRef ReceiverSymbol;
  bool Satisfied;

public:
  SuperDeallocBRVisitor(SymbolRef ReceiverSymbol)
      : ReceiverSymbol(ReceiverSymbol), Satisfied(false) {}

  PathDiagnosticPieceRef VisitNode(const ExplodedNode *Succ,
                                   BugReporterContext &BRC,
                                   PathSensitiveBugReport &BR) override;

  void Profile(llvm::FoldingSetNodeID &ID) const override {
    ID.Add(ReceiverSymbol);
  }
};
} // End anonymous namespace.

void ObjCSuperDeallocChecker::checkPreObjCMessage(const ObjCMethodCall &M,
                                                  CheckerContext &C) const {

  ProgramStateRef State = C.getState();
  SymbolRef ReceiverSymbol = M.getReceiverSVal().getAsSymbol();
  if (!ReceiverSymbol) {
    diagnoseCallArguments(M, C);
    return;
  }

  bool AlreadyCalled = State->contains<CalledSuperDealloc>(ReceiverSymbol);
  if (!AlreadyCalled)
    return;

  StringRef Desc;

  if (isSuperDeallocMessage(M)) {
    Desc = "[super dealloc] should not be called multiple times";
  } else {
    Desc = StringRef();
  }

  reportUseAfterDealloc(ReceiverSymbol, Desc, M.getOriginExpr(), C);
}

void ObjCSuperDeallocChecker::checkPreCall(const CallEvent &Call,
                                           CheckerContext &C) const {
  diagnoseCallArguments(Call, C);
}

void ObjCSuperDeallocChecker::checkPostObjCMessage(const ObjCMethodCall &M,
                                                   CheckerContext &C) const {
  // Check for [super dealloc] method call.
  if (!isSuperDeallocMessage(M))
    return;

  ProgramStateRef State = C.getState();
  const LocationContext *LC = C.getLocationContext();
  SymbolRef SelfSymbol = State->getSelfSVal(LC).getAsSymbol();
  assert(SelfSymbol && "No receiver symbol at call to [super dealloc]?");

  // We add this transition in checkPostObjCMessage to avoid warning when
  // we inline a call to [super dealloc] where the inlined call itself
  // calls [super dealloc].
  State = State->add<CalledSuperDealloc>(SelfSymbol);
  C.addTransition(State);
}

void ObjCSuperDeallocChecker::checkLocation(SVal L, bool IsLoad, const Stmt *S,
                                  CheckerContext &C) const {
  SymbolRef BaseSym = L.getLocSymbolInBase();
  if (!BaseSym)
    return;

  ProgramStateRef State = C.getState();

  if (!State->contains<CalledSuperDealloc>(BaseSym))
    return;

  const MemRegion *R = L.getAsRegion();
  if (!R)
    return;

  // Climb the super regions to find the base symbol while recording
  // the second-to-last region for error reporting.
  const MemRegion *PriorSubRegion = nullptr;
  while (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
    if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SR)) {
      BaseSym = SymR->getSymbol();
      break;
    } else {
      R = SR->getSuperRegion();
      PriorSubRegion = SR;
    }
  }

  StringRef Desc = StringRef();
  auto *IvarRegion = dyn_cast_or_null<ObjCIvarRegion>(PriorSubRegion);

  std::string Buf;
  llvm::raw_string_ostream OS(Buf);
  if (IvarRegion) {
    OS << "Use of instance variable '" << *IvarRegion->getDecl() <<
          "' after 'self' has been deallocated";
    Desc = Buf;
  }

  reportUseAfterDealloc(BaseSym, Desc, S, C);
}

/// Report a use-after-dealloc on Sym. If not empty,
/// Desc will be used to describe the error; otherwise,
/// a default warning will be used.
void ObjCSuperDeallocChecker::reportUseAfterDealloc(SymbolRef Sym,
                                                    StringRef Desc,
                                                    const Stmt *S,
                                                    CheckerContext &C) const {
  // We have a use of self after free.
  // This likely causes a crash, so stop exploring the
  // path by generating a sink.
  ExplodedNode *ErrNode = C.generateErrorNode();
  // If we've already reached this node on another path, return.
  if (!ErrNode)
    return;

  if (Desc.empty())
    Desc = "Use of 'self' after it has been deallocated";

  // Generate the report.
  auto BR = std::make_unique<PathSensitiveBugReport>(DoubleSuperDeallocBugType,
                                                     Desc, ErrNode);
  BR->addRange(S->getSourceRange());
  BR->addVisitor(std::make_unique<SuperDeallocBRVisitor>(Sym));
  C.emitReport(std::move(BR));
}

/// Diagnose if any of the arguments to CE have already been
/// dealloc'd.
void ObjCSuperDeallocChecker::diagnoseCallArguments(const CallEvent &CE,
                                                    CheckerContext &C) const {
  ProgramStateRef State = C.getState();
  unsigned ArgCount = CE.getNumArgs();
  for (unsigned I = 0; I < ArgCount; I++) {
    SymbolRef Sym = CE.getArgSVal(I).getAsSymbol();
    if (!Sym)
      continue;

    if (State->contains<CalledSuperDealloc>(Sym)) {
      reportUseAfterDealloc(Sym, StringRef(), CE.getArgExpr(I), C);
      return;
    }
  }
}

void
ObjCSuperDeallocChecker::initIdentifierInfoAndSelectors(ASTContext &Ctx) const {
  if (IIdealloc)
    return;

  IIdealloc = &Ctx.Idents.get("dealloc");
  IINSObject = &Ctx.Idents.get("NSObject");

  SELdealloc = Ctx.Selectors.getSelector(0, &IIdealloc);
}

bool
ObjCSuperDeallocChecker::isSuperDeallocMessage(const ObjCMethodCall &M) const {
  if (M.getOriginExpr()->getReceiverKind() != ObjCMessageExpr::SuperInstance)
    return false;

  ASTContext &Ctx = M.getState()->getStateManager().getContext();
  initIdentifierInfoAndSelectors(Ctx);

  return M.getSelector() == SELdealloc;
}

PathDiagnosticPieceRef
SuperDeallocBRVisitor::VisitNode(const ExplodedNode *Succ,
                                 BugReporterContext &BRC,
                                 PathSensitiveBugReport &) {
  if (Satisfied)
    return nullptr;

  ProgramStateRef State = Succ->getState();

  bool CalledNow =
      Succ->getState()->contains<CalledSuperDealloc>(ReceiverSymbol);
  bool CalledBefore =
      Succ->getFirstPred()->getState()->contains<CalledSuperDealloc>(
          ReceiverSymbol);

  // Is Succ the node on which the analyzer noted that [super dealloc] was
  // called on ReceiverSymbol?
  if (CalledNow && !CalledBefore) {
    Satisfied = true;

    ProgramPoint P = Succ->getLocation();
    PathDiagnosticLocation L =
        PathDiagnosticLocation::create(P, BRC.getSourceManager());

    if (!L.isValid() || !L.asLocation().isValid())
      return nullptr;

    return std::make_shared<PathDiagnosticEventPiece>(
        L, "[super dealloc] called here");
  }

  return nullptr;
}

//===----------------------------------------------------------------------===//
// Checker Registration.
//===----------------------------------------------------------------------===//

void ento::registerObjCSuperDeallocChecker(CheckerManager &Mgr) {
  Mgr.registerChecker<ObjCSuperDeallocChecker>();
}

bool ento::shouldRegisterObjCSuperDeallocChecker(const CheckerManager &mgr) {
  return true;
}
