//===--- DanglingHandleCheck.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 "DanglingHandleCheck.h"
#include "../utils/Matchers.h"
#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;
using namespace clang::tidy::matchers;

namespace clang {
namespace tidy {
namespace bugprone {

namespace {

ast_matchers::internal::BindableMatcher<Stmt>
handleFrom(const ast_matchers::internal::Matcher<RecordDecl> &IsAHandle,
           const ast_matchers::internal::Matcher<Expr> &Arg) {
  return expr(
      anyOf(cxxConstructExpr(hasDeclaration(cxxMethodDecl(ofClass(IsAHandle))),
                             hasArgument(0, Arg)),
            cxxMemberCallExpr(hasType(cxxRecordDecl(IsAHandle)),
                              callee(memberExpr(member(cxxConversionDecl()))),
                              on(Arg))));
}

ast_matchers::internal::Matcher<Stmt> handleFromTemporaryValue(
    const ast_matchers::internal::Matcher<RecordDecl> &IsAHandle) {
  // If a ternary operator returns a temporary value, then both branches hold a
  // temporary value. If one of them is not a temporary then it must be copied
  // into one to satisfy the type of the operator.
  const auto TemporaryTernary =
      conditionalOperator(hasTrueExpression(cxxBindTemporaryExpr()),
                          hasFalseExpression(cxxBindTemporaryExpr()));

  return handleFrom(IsAHandle, anyOf(cxxBindTemporaryExpr(), TemporaryTernary));
}

ast_matchers::internal::Matcher<RecordDecl> isASequence() {
  return hasAnyName("::std::deque", "::std::forward_list", "::std::list",
                    "::std::vector");
}

ast_matchers::internal::Matcher<RecordDecl> isASet() {
  return hasAnyName("::std::set", "::std::multiset", "::std::unordered_set",
                    "::std::unordered_multiset");
}

ast_matchers::internal::Matcher<RecordDecl> isAMap() {
  return hasAnyName("::std::map", "::std::multimap", "::std::unordered_map",
                    "::std::unordered_multimap");
}

ast_matchers::internal::BindableMatcher<Stmt> makeContainerMatcher(
    const ast_matchers::internal::Matcher<RecordDecl> &IsAHandle) {
  // This matcher could be expanded to detect:
  //  - Constructors: eg. vector<string_view>(3, string("A"));
  //  - emplace*(): This requires a different logic to determine that
  //                the conversion will happen inside the container.
  //  - map's insert: This requires detecting that the pair conversion triggers
  //                  the bug. A little more complicated than what we have now.
  return callExpr(
      hasAnyArgument(
          ignoringParenImpCasts(handleFromTemporaryValue(IsAHandle))),
      anyOf(
          // For sequences: assign, push_back, resize.
          cxxMemberCallExpr(
              callee(functionDecl(hasAnyName("assign", "push_back", "resize"))),
              on(expr(hasType(hasUnqualifiedDesugaredType(
                  recordType(hasDeclaration(recordDecl(isASequence())))))))),
          // For sequences and sets: insert.
          cxxMemberCallExpr(callee(functionDecl(hasName("insert"))),
                            on(expr(hasType(hasUnqualifiedDesugaredType(
                                recordType(hasDeclaration(recordDecl(
                                    anyOf(isASequence(), isASet()))))))))),
          // For maps: operator[].
          cxxOperatorCallExpr(callee(cxxMethodDecl(ofClass(isAMap()))),
                              hasOverloadedOperatorName("[]"))));
}

} // anonymous namespace

DanglingHandleCheck::DanglingHandleCheck(StringRef Name,
                                         ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      HandleClasses(utils::options::parseStringList(Options.get(
          "HandleClasses",
          "std::basic_string_view;std::experimental::basic_string_view"))),
      IsAHandle(cxxRecordDecl(hasAnyName(std::vector<StringRef>(
                                  HandleClasses.begin(), HandleClasses.end())))
                    .bind("handle")) {}

void DanglingHandleCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "HandleClasses",
                utils::options::serializeStringList(HandleClasses));
}

void DanglingHandleCheck::registerMatchersForVariables(MatchFinder *Finder) {
  const auto ConvertedHandle = handleFromTemporaryValue(IsAHandle);

  // Find 'Handle foo(ReturnsAValue());'
  Finder->addMatcher(
      varDecl(hasType(hasUnqualifiedDesugaredType(
                  recordType(hasDeclaration(cxxRecordDecl(IsAHandle))))),
              hasInitializer(
                  exprWithCleanups(has(ignoringParenImpCasts(ConvertedHandle)))
                      .bind("bad_stmt"))),
      this);

  // Find 'Handle foo = ReturnsAValue();'
  Finder->addMatcher(
      traverse(ast_type_traits::TK_AsIs,
               varDecl(hasType(hasUnqualifiedDesugaredType(recordType(
                           hasDeclaration(cxxRecordDecl(IsAHandle))))),
                       unless(parmVarDecl()),
                       hasInitializer(exprWithCleanups(
                                          has(ignoringParenImpCasts(handleFrom(
                                              IsAHandle, ConvertedHandle))))
                                          .bind("bad_stmt")))),
      this);
  // Find 'foo = ReturnsAValue();  // foo is Handle'
  Finder->addMatcher(
      traverse(ast_type_traits::TK_AsIs,
               cxxOperatorCallExpr(callee(cxxMethodDecl(ofClass(IsAHandle))),
                                   hasOverloadedOperatorName("="),
                                   hasArgument(1, ConvertedHandle))
                   .bind("bad_stmt")),
      this);

  // Container insertions that will dangle.
  Finder->addMatcher(traverse(ast_type_traits::TK_AsIs,
                              makeContainerMatcher(IsAHandle).bind("bad_stmt")),
                     this);
}

void DanglingHandleCheck::registerMatchersForReturn(MatchFinder *Finder) {
  // Return a local.
  Finder->addMatcher(
      traverse(
          ast_type_traits::TK_AsIs,
          returnStmt(
              // The AST contains two constructor calls:
              //   1. Value to Handle conversion.
              //   2. Handle copy construction.
              // We have to match both.
              has(ignoringImplicit(handleFrom(
                  IsAHandle,
                  handleFrom(IsAHandle,
                             declRefExpr(to(varDecl(
                                 // Is function scope ...
                                 hasAutomaticStorageDuration(),
                                 // ... and it is a local array or Value.
                                 anyOf(hasType(arrayType()),
                                       hasType(hasUnqualifiedDesugaredType(
                                           recordType(hasDeclaration(recordDecl(
                                               unless(IsAHandle)))))))))))))),
              // Temporary fix for false positives inside lambdas.
              unless(hasAncestor(lambdaExpr())))
              .bind("bad_stmt")),
      this);

  // Return a temporary.
  Finder->addMatcher(
      traverse(
          ast_type_traits::TK_AsIs,
          returnStmt(has(exprWithCleanups(has(ignoringParenImpCasts(handleFrom(
                         IsAHandle, handleFromTemporaryValue(IsAHandle)))))))
              .bind("bad_stmt")),
      this);
}

void DanglingHandleCheck::registerMatchers(MatchFinder *Finder) {
  registerMatchersForVariables(Finder);
  registerMatchersForReturn(Finder);
}

void DanglingHandleCheck::check(const MatchFinder::MatchResult &Result) {
  auto *Handle = Result.Nodes.getNodeAs<CXXRecordDecl>("handle");
  diag(Result.Nodes.getNodeAs<Stmt>("bad_stmt")->getBeginLoc(),
       "%0 outlives its value")
      << Handle->getQualifiedNameAsString();
}

} // namespace bugprone
} // namespace tidy
} // namespace clang
