//===--- 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 {
namespace tidy {
namespace 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 misc
} // namespace tidy
} // namespace clang
