//===--- ThrowByValueCatchByReferenceCheck.cpp - clang-tidy----------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "ThrowByValueCatchByReferenceCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/OperationKinds.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;

namespace clang::tidy::misc {

ThrowByValueCatchByReferenceCheck::ThrowByValueCatchByReferenceCheck(
    StringRef Name, ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      CheckAnonymousTemporaries(Options.get("CheckThrowTemporaries", true)),
      WarnOnLargeObject(Options.get("WarnOnLargeObject", false)),
      // Cannot access `ASTContext` from here so set it to an extremal value.
      MaxSizeOptions(
          Options.get("MaxSize", std::numeric_limits<uint64_t>::max())),
      MaxSize(MaxSizeOptions) {}

void ThrowByValueCatchByReferenceCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(cxxThrowExpr().bind("throw"), this);
  Finder->addMatcher(cxxCatchStmt().bind("catch"), this);
}

void ThrowByValueCatchByReferenceCheck::storeOptions(
    ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "CheckThrowTemporaries", true);
  Options.store(Opts, "WarnOnLargeObjects", WarnOnLargeObject);
  Options.store(Opts, "MaxSize", MaxSizeOptions);
}

void ThrowByValueCatchByReferenceCheck::check(
    const MatchFinder::MatchResult &Result) {
  diagnoseThrowLocations(Result.Nodes.getNodeAs<CXXThrowExpr>("throw"));
  diagnoseCatchLocations(Result.Nodes.getNodeAs<CXXCatchStmt>("catch"),
                         *Result.Context);
}

bool ThrowByValueCatchByReferenceCheck::isFunctionParameter(
    const DeclRefExpr *DeclRefExpr) {
  return isa<ParmVarDecl>(DeclRefExpr->getDecl());
}

bool ThrowByValueCatchByReferenceCheck::isCatchVariable(
    const DeclRefExpr *DeclRefExpr) {
  auto *ValueDecl = DeclRefExpr->getDecl();
  if (auto *VarDecl = dyn_cast<clang::VarDecl>(ValueDecl))
    return VarDecl->isExceptionVariable();
  return false;
}

bool ThrowByValueCatchByReferenceCheck::isFunctionOrCatchVar(
    const DeclRefExpr *DeclRefExpr) {
  return isFunctionParameter(DeclRefExpr) || isCatchVariable(DeclRefExpr);
}

void ThrowByValueCatchByReferenceCheck::diagnoseThrowLocations(
    const CXXThrowExpr *ThrowExpr) {
  if (!ThrowExpr)
    return;
  auto *SubExpr = ThrowExpr->getSubExpr();
  if (!SubExpr)
    return;
  auto QualType = SubExpr->getType();
  if (QualType->isPointerType()) {
    // The code is throwing a pointer.
    // In case it is string literal, it is safe and we return.
    auto *Inner = SubExpr->IgnoreParenImpCasts();
    if (isa<StringLiteral>(Inner))
      return;
    // If it's a variable from a catch statement, we return as well.
    auto *DeclRef = dyn_cast<DeclRefExpr>(Inner);
    if (DeclRef && isCatchVariable(DeclRef)) {
      return;
    }
    diag(SubExpr->getBeginLoc(), "throw expression throws a pointer; it should "
                                 "throw a non-pointer value instead");
  }
  // If the throw statement does not throw by pointer then it throws by value
  // which is ok.
  // There are addition checks that emit diagnosis messages if the thrown value
  // is not an RValue. See:
  // https://www.securecoding.cert.org/confluence/display/cplusplus/ERR09-CPP.+Throw+anonymous+temporaries
  // This behavior can be influenced by an option.

  // If we encounter a CXXThrowExpr, we move through all casts until you either
  // encounter a DeclRefExpr or a CXXConstructExpr.
  // If it's a DeclRefExpr, we emit a message if the referenced variable is not
  // a catch variable or function parameter.
  // When encountering a CopyOrMoveConstructor: emit message if after casts,
  // the expression is a LValue
  if (CheckAnonymousTemporaries) {
    bool Emit = false;
    auto *CurrentSubExpr = SubExpr->IgnoreImpCasts();
    const auto *VariableReference = dyn_cast<DeclRefExpr>(CurrentSubExpr);
    const auto *ConstructorCall = dyn_cast<CXXConstructExpr>(CurrentSubExpr);
    // If we have a DeclRefExpr, we flag for emitting a diagnosis message in
    // case the referenced variable is neither a function parameter nor a
    // variable declared in the catch statement.
    if (VariableReference)
      Emit = !isFunctionOrCatchVar(VariableReference);
    else if (ConstructorCall &&
             ConstructorCall->getConstructor()->isCopyOrMoveConstructor()) {
      // If we have a copy / move construction, we emit a diagnosis message if
      // the object that we copy construct from is neither a function parameter
      // nor a variable declared in a catch statement
      auto ArgIter =
          ConstructorCall
              ->arg_begin(); // there's only one for copy constructors
      auto *CurrentSubExpr = (*ArgIter)->IgnoreImpCasts();
      if (CurrentSubExpr->isLValue()) {
        if (auto *Tmp = dyn_cast<DeclRefExpr>(CurrentSubExpr))
          Emit = !isFunctionOrCatchVar(Tmp);
        else if (isa<CallExpr>(CurrentSubExpr))
          Emit = true;
      }
    }
    if (Emit)
      diag(SubExpr->getBeginLoc(),
           "throw expression should throw anonymous temporary values instead");
  }
}

void ThrowByValueCatchByReferenceCheck::diagnoseCatchLocations(
    const CXXCatchStmt *CatchStmt, ASTContext &Context) {
  if (!CatchStmt)
    return;
  auto CaughtType = CatchStmt->getCaughtType();
  if (CaughtType.isNull())
    return;
  auto *VarDecl = CatchStmt->getExceptionDecl();
  if (const auto *PT = CaughtType.getCanonicalType()->getAs<PointerType>()) {
    const char *DiagMsgCatchReference =
        "catch handler catches a pointer value; "
        "should throw a non-pointer value and "
        "catch by reference instead";
    // We do not diagnose when catching pointer to strings since we also allow
    // throwing string literals.
    if (!PT->getPointeeType()->isAnyCharacterType())
      diag(VarDecl->getBeginLoc(), DiagMsgCatchReference);
  } else if (!CaughtType->isReferenceType()) {
    const char *DiagMsgCatchReference = "catch handler catches by value; "
                                        "should catch by reference instead";
    // If it's not a pointer and not a reference then it must be caught "by
    // value". In this case we should emit a diagnosis message unless the type
    // is trivial.
    if (!CaughtType.isTrivialType(Context)) {
      diag(VarDecl->getBeginLoc(), DiagMsgCatchReference);
    } else if (WarnOnLargeObject) {
      // If the type is trivial, then catching it by reference is not dangerous.
      // However, catching large objects by value decreases the performance.

      // We can now access `ASTContext` so if `MaxSize` is an extremal value
      // then set it to the size of `size_t`.
      if (MaxSize == std::numeric_limits<uint64_t>::max())
        MaxSize = Context.getTypeSize(Context.getSizeType());
      if (Context.getTypeSize(CaughtType) > MaxSize)
        diag(VarDecl->getBeginLoc(), DiagMsgCatchReference);
    }
  }
}

} // namespace clang::tidy::misc
