//=- RunLoopAutoreleaseLeakChecker.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
//
//
//===----------------------------------------------------------------------===//
//
// A checker for detecting leaks resulting from allocating temporary
// autoreleased objects before starting the main run loop.
//
// Checks for two antipatterns:
// 1. ObjCMessageExpr followed by [[NSRunLoop mainRunLoop] run] in the same
// autorelease pool.
// 2. ObjCMessageExpr followed by [[NSRunLoop mainRunLoop] run] in no
// autorelease pool.
//
// Any temporary objects autoreleased in code called in those expressions
// will not be deallocated until the program exits, and are effectively leaks.
//
//===----------------------------------------------------------------------===//
//

#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.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/ExprEngine.h"

using namespace clang;
using namespace ento;
using namespace ast_matchers;

namespace {

const char * RunLoopBind = "NSRunLoopM";
const char * RunLoopRunBind = "RunLoopRunM";
const char * OtherMsgBind = "OtherMessageSentM";
const char * AutoreleasePoolBind = "AutoreleasePoolM";
const char * OtherStmtAutoreleasePoolBind = "OtherAutoreleasePoolM";

class RunLoopAutoreleaseLeakChecker : public Checker<check::ASTCodeBody> {

public:
  void checkASTCodeBody(const Decl *D,
                        AnalysisManager &AM,
                        BugReporter &BR) const;

};

} // end anonymous namespace

/// \return Whether {@code A} occurs before {@code B} in traversal of
/// {@code Parent}.
/// Conceptually a very incomplete/unsound approximation of happens-before
/// relationship (A is likely to be evaluated before B),
/// but useful enough in this case.
static bool seenBefore(const Stmt *Parent, const Stmt *A, const Stmt *B) {
  for (const Stmt *C : Parent->children()) {
    if (!C) continue;

    if (C == A)
      return true;

    if (C == B)
      return false;

    return seenBefore(C, A, B);
  }
  return false;
}

static void emitDiagnostics(BoundNodes &Match,
                            const Decl *D,
                            BugReporter &BR,
                            AnalysisManager &AM,
                            const RunLoopAutoreleaseLeakChecker *Checker) {

  assert(D->hasBody());
  const Stmt *DeclBody = D->getBody();

  AnalysisDeclContext *ADC = AM.getAnalysisDeclContext(D);

  const auto *ME = Match.getNodeAs<ObjCMessageExpr>(OtherMsgBind);
  assert(ME);

  const auto *AP =
      Match.getNodeAs<ObjCAutoreleasePoolStmt>(AutoreleasePoolBind);
  const auto *OAP =
      Match.getNodeAs<ObjCAutoreleasePoolStmt>(OtherStmtAutoreleasePoolBind);
  bool HasAutoreleasePool = (AP != nullptr);

  const auto *RL = Match.getNodeAs<ObjCMessageExpr>(RunLoopBind);
  const auto *RLR = Match.getNodeAs<Stmt>(RunLoopRunBind);
  assert(RLR && "Run loop launch not found");
  assert(ME != RLR);

  // Launch of run loop occurs before the message-sent expression is seen.
  if (seenBefore(DeclBody, RLR, ME))
    return;

  if (HasAutoreleasePool && (OAP != AP))
    return;

  PathDiagnosticLocation Location = PathDiagnosticLocation::createBegin(
    ME, BR.getSourceManager(), ADC);
  SourceRange Range = ME->getSourceRange();

  BR.EmitBasicReport(ADC->getDecl(), Checker,
                     /*Name=*/"Memory leak inside autorelease pool",
                     /*BugCategory=*/"Memory",
                     /*Name=*/
                     (Twine("Temporary objects allocated in the") +
                      " autorelease pool " +
                      (HasAutoreleasePool ? "" : "of last resort ") +
                      "followed by the launch of " +
                      (RL ? "main run loop " : "xpc_main ") +
                      "may never get released; consider moving them to a "
                      "separate autorelease pool")
                         .str(),
                     Location, Range);
}

static StatementMatcher getRunLoopRunM(StatementMatcher Extra = anything()) {
  StatementMatcher MainRunLoopM =
      objcMessageExpr(hasSelector("mainRunLoop"),
                      hasReceiverType(asString("NSRunLoop")),
                      Extra)
          .bind(RunLoopBind);

  StatementMatcher MainRunLoopRunM = objcMessageExpr(hasSelector("run"),
                         hasReceiver(MainRunLoopM),
                         Extra).bind(RunLoopRunBind);

  StatementMatcher XPCRunM =
      callExpr(callee(functionDecl(hasName("xpc_main")))).bind(RunLoopRunBind);
  return anyOf(MainRunLoopRunM, XPCRunM);
}

static StatementMatcher getOtherMessageSentM(StatementMatcher Extra = anything()) {
  return objcMessageExpr(unless(anyOf(equalsBoundNode(RunLoopBind),
                                      equalsBoundNode(RunLoopRunBind))),
                         Extra)
      .bind(OtherMsgBind);
}

static void
checkTempObjectsInSamePool(const Decl *D, AnalysisManager &AM, BugReporter &BR,
                           const RunLoopAutoreleaseLeakChecker *Chkr) {
  StatementMatcher RunLoopRunM = getRunLoopRunM();
  StatementMatcher OtherMessageSentM = getOtherMessageSentM(
    hasAncestor(autoreleasePoolStmt().bind(OtherStmtAutoreleasePoolBind)));

  StatementMatcher RunLoopInAutorelease =
      autoreleasePoolStmt(
        hasDescendant(RunLoopRunM),
        hasDescendant(OtherMessageSentM)).bind(AutoreleasePoolBind);

  DeclarationMatcher GroupM = decl(hasDescendant(RunLoopInAutorelease));

  auto Matches = match(GroupM, *D, AM.getASTContext());
  for (BoundNodes Match : Matches)
    emitDiagnostics(Match, D, BR, AM, Chkr);
}

static void
checkTempObjectsInNoPool(const Decl *D, AnalysisManager &AM, BugReporter &BR,
                         const RunLoopAutoreleaseLeakChecker *Chkr) {

  auto NoPoolM = unless(hasAncestor(autoreleasePoolStmt()));

  StatementMatcher RunLoopRunM = getRunLoopRunM(NoPoolM);
  StatementMatcher OtherMessageSentM = getOtherMessageSentM(NoPoolM);

  DeclarationMatcher GroupM = functionDecl(
    isMain(),
    hasDescendant(RunLoopRunM),
    hasDescendant(OtherMessageSentM)
  );

  auto Matches = match(GroupM, *D, AM.getASTContext());

  for (BoundNodes Match : Matches)
    emitDiagnostics(Match, D, BR, AM, Chkr);

}

void RunLoopAutoreleaseLeakChecker::checkASTCodeBody(const Decl *D,
                        AnalysisManager &AM,
                        BugReporter &BR) const {
  checkTempObjectsInSamePool(D, AM, BR, this);
  checkTempObjectsInNoPool(D, AM, BR, this);
}

void ento::registerRunLoopAutoreleaseLeakChecker(CheckerManager &mgr) {
  mgr.registerChecker<RunLoopAutoreleaseLeakChecker>();
}

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