//===--- ThrowByValueCatchByReferenceCheck.cpp - clang-tidy----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#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)) {}

void ThrowByValueCatchByReferenceCheck::registerMatchers(MatchFinder *Finder) {
  // This is a C++ only check thus we register the matchers only for C++
  if (!getLangOpts().CPlusPlus)
    return;

  Finder->addMatcher(cxxThrowExpr().bind("throw"), this);
  Finder->addMatcher(cxxCatchStmt().bind("catch"), this);
}

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

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<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 strng 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->getLocStart(), "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->getLocStart(),
           "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->getLocStart(), 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->getLocStart(), diagMsgCatchReference);
  }
}

} // namespace misc
} // namespace tidy
} // namespace clang
