//===- 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 = OS.str();
  }

  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;
}
