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

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace bugprone {

// Semicolon separated list of known string compare-like functions. The list
// must ends with a semicolon.
static const char KnownStringCompareFunctions[] = "__builtin_memcmp;"
                                                  "__builtin_strcasecmp;"
                                                  "__builtin_strcmp;"
                                                  "__builtin_strncasecmp;"
                                                  "__builtin_strncmp;"
                                                  "_mbscmp;"
                                                  "_mbscmp_l;"
                                                  "_mbsicmp;"
                                                  "_mbsicmp_l;"
                                                  "_mbsnbcmp;"
                                                  "_mbsnbcmp_l;"
                                                  "_mbsnbicmp;"
                                                  "_mbsnbicmp_l;"
                                                  "_mbsncmp;"
                                                  "_mbsncmp_l;"
                                                  "_mbsnicmp;"
                                                  "_mbsnicmp_l;"
                                                  "_memicmp;"
                                                  "_memicmp_l;"
                                                  "_stricmp;"
                                                  "_stricmp_l;"
                                                  "_strnicmp;"
                                                  "_strnicmp_l;"
                                                  "_wcsicmp;"
                                                  "_wcsicmp_l;"
                                                  "_wcsnicmp;"
                                                  "_wcsnicmp_l;"
                                                  "lstrcmp;"
                                                  "lstrcmpi;"
                                                  "memcmp;"
                                                  "memicmp;"
                                                  "strcasecmp;"
                                                  "strcmp;"
                                                  "strcmpi;"
                                                  "stricmp;"
                                                  "strncasecmp;"
                                                  "strncmp;"
                                                  "strnicmp;"
                                                  "wcscasecmp;"
                                                  "wcscmp;"
                                                  "wcsicmp;"
                                                  "wcsncmp;"
                                                  "wcsnicmp;"
                                                  "wmemcmp;";

SuspiciousStringCompareCheck::SuspiciousStringCompareCheck(
    StringRef Name, ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      WarnOnImplicitComparison(Options.get("WarnOnImplicitComparison", true)),
      WarnOnLogicalNotComparison(
          Options.get("WarnOnLogicalNotComparison", false)),
      StringCompareLikeFunctions(
          Options.get("StringCompareLikeFunctions", "")) {}

void SuspiciousStringCompareCheck::storeOptions(
    ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "WarnOnImplicitComparison", WarnOnImplicitComparison);
  Options.store(Opts, "WarnOnLogicalNotComparison", WarnOnLogicalNotComparison);
  Options.store(Opts, "StringCompareLikeFunctions", StringCompareLikeFunctions);
}

void SuspiciousStringCompareCheck::registerMatchers(MatchFinder *Finder) {
  // Match relational operators.
  const auto ComparisonUnaryOperator = unaryOperator(hasOperatorName("!"));
  const auto ComparisonBinaryOperator = binaryOperator(isComparisonOperator());
  const auto ComparisonOperator =
      expr(anyOf(ComparisonUnaryOperator, ComparisonBinaryOperator));

  // Add the list of known string compare-like functions and add user-defined
  // functions.
  std::vector<std::string> FunctionNames = utils::options::parseStringList(
      (llvm::Twine(KnownStringCompareFunctions) + StringCompareLikeFunctions)
          .str());

  // Match a call to a string compare functions.
  const auto FunctionCompareDecl =
      functionDecl(hasAnyName(std::vector<StringRef>(FunctionNames.begin(),
                                                     FunctionNames.end())))
          .bind("decl");
  const auto DirectStringCompareCallExpr =
      callExpr(hasDeclaration(FunctionCompareDecl)).bind("call");
  const auto MacroStringCompareCallExpr = conditionalOperator(anyOf(
      hasTrueExpression(ignoringParenImpCasts(DirectStringCompareCallExpr)),
      hasFalseExpression(ignoringParenImpCasts(DirectStringCompareCallExpr))));
  // The implicit cast is not present in C.
  const auto StringCompareCallExpr = ignoringParenImpCasts(
      anyOf(DirectStringCompareCallExpr, MacroStringCompareCallExpr));

  if (WarnOnImplicitComparison) {
    // Detect suspicious calls to string compare:
    //     'if (strcmp())'  ->  'if (strcmp() != 0)'
    Finder->addMatcher(
        stmt(anyOf(mapAnyOf(ifStmt, whileStmt, doStmt, forStmt)
                       .with(hasCondition(StringCompareCallExpr)),
                   binaryOperator(hasAnyOperatorName("&&", "||"),
                                  hasEitherOperand(StringCompareCallExpr))))
            .bind("missing-comparison"),
        this);
  }

  if (WarnOnLogicalNotComparison) {
    // Detect suspicious calls to string compared with '!' operator:
    //     'if (!strcmp())'  ->  'if (strcmp() == 0)'
    Finder->addMatcher(unaryOperator(hasOperatorName("!"),
                                     hasUnaryOperand(ignoringParenImpCasts(
                                         StringCompareCallExpr)))
                           .bind("logical-not-comparison"),
                       this);
  }

  // Detect suspicious cast to an inconsistent type (i.e. not integer type).
  Finder->addMatcher(
      traverse(TK_AsIs,
               implicitCastExpr(unless(hasType(isInteger())),
                                hasSourceExpression(StringCompareCallExpr))
                   .bind("invalid-conversion")),
      this);

  // Detect suspicious operator with string compare function as operand.
  Finder->addMatcher(
      binaryOperator(unless(anyOf(isComparisonOperator(), hasOperatorName("&&"),
                                  hasOperatorName("||"), hasOperatorName("="))),
                     hasEitherOperand(StringCompareCallExpr))
          .bind("suspicious-operator"),
      this);

  // Detect comparison to invalid constant: 'strcmp() == -1'.
  const auto InvalidLiteral = ignoringParenImpCasts(
      anyOf(integerLiteral(unless(equals(0))),
            unaryOperator(
                hasOperatorName("-"),
                has(ignoringParenImpCasts(integerLiteral(unless(equals(0)))))),
            characterLiteral(), cxxBoolLiteral()));

  Finder->addMatcher(
      binaryOperator(isComparisonOperator(),
                     hasOperands(StringCompareCallExpr, InvalidLiteral))
          .bind("invalid-comparison"),
      this);
}

void SuspiciousStringCompareCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *Decl = Result.Nodes.getNodeAs<FunctionDecl>("decl");
  const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call");
  assert(Decl != nullptr && Call != nullptr);

  if (Result.Nodes.getNodeAs<Stmt>("missing-comparison")) {
    SourceLocation EndLoc = Lexer::getLocForEndOfToken(
        Call->getRParenLoc(), 0, Result.Context->getSourceManager(),
        getLangOpts());

    diag(Call->getBeginLoc(),
         "function %0 is called without explicitly comparing result")
        << Decl << FixItHint::CreateInsertion(EndLoc, " != 0");
  }

  if (const auto *E = Result.Nodes.getNodeAs<Expr>("logical-not-comparison")) {
    SourceLocation EndLoc = Lexer::getLocForEndOfToken(
        Call->getRParenLoc(), 0, Result.Context->getSourceManager(),
        getLangOpts());
    SourceLocation NotLoc = E->getBeginLoc();

    diag(Call->getBeginLoc(),
         "function %0 is compared using logical not operator")
        << Decl
        << FixItHint::CreateRemoval(
               CharSourceRange::getTokenRange(NotLoc, NotLoc))
        << FixItHint::CreateInsertion(EndLoc, " == 0");
  }

  if (Result.Nodes.getNodeAs<Stmt>("invalid-comparison")) {
    diag(Call->getBeginLoc(),
         "function %0 is compared to a suspicious constant")
        << Decl;
  }

  if (const auto *BinOp =
          Result.Nodes.getNodeAs<BinaryOperator>("suspicious-operator")) {
    diag(Call->getBeginLoc(), "results of function %0 used by operator '%1'")
        << Decl << BinOp->getOpcodeStr();
  }

  if (Result.Nodes.getNodeAs<Stmt>("invalid-conversion")) {
    diag(Call->getBeginLoc(), "function %0 has suspicious implicit cast")
        << Decl;
  }
}

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