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

using namespace clang::ast_matchers;
using namespace clang::ast_matchers::internal;

namespace clang {
namespace tidy {
namespace hicpp {

SignedBitwiseCheck::SignedBitwiseCheck(StringRef Name,
                                       ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      IgnorePositiveIntegerLiterals(
          Options.get("IgnorePositiveIntegerLiterals", false)) {}

void SignedBitwiseCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "IgnorePositiveIntegerLiterals",
                IgnorePositiveIntegerLiterals);
}

void SignedBitwiseCheck::registerMatchers(MatchFinder *Finder) {
  const auto SignedIntegerOperand =
      (IgnorePositiveIntegerLiterals
           ? expr(ignoringImpCasts(hasType(isSignedInteger())),
                  unless(integerLiteral()))
           : expr(ignoringImpCasts(hasType(isSignedInteger()))))
          .bind("signed-operand");

  // The standard [bitmask.types] allows some integral types to be implemented
  // as signed types. Exclude these types from diagnosing for bitwise or(|) and
  // bitwise and(&). Shifting and complementing such values is still not
  // allowed.
  const auto BitmaskType = namedDecl(
      hasAnyName("::std::locale::category", "::std::ctype_base::mask",
                 "::std::ios_base::fmtflags", "::std::ios_base::iostate",
                 "::std::ios_base::openmode"));
  const auto IsStdBitmask = ignoringImpCasts(declRefExpr(hasType(BitmaskType)));

  // Match binary bitwise operations on signed integer arguments.
  Finder->addMatcher(
      binaryOperator(hasAnyOperatorName("^", "|", "&", "^=", "|=", "&="),

                     unless(allOf(hasLHS(IsStdBitmask), hasRHS(IsStdBitmask))),

                     hasEitherOperand(SignedIntegerOperand),
                     hasLHS(hasType(isInteger())), hasRHS(hasType(isInteger())))
          .bind("binary-no-sign-interference"),
      this);

  // Shifting and complement is not allowed for any signed integer type because
  // the sign bit may corrupt the result.
  Finder->addMatcher(
      binaryOperator(hasAnyOperatorName("<<", ">>", "<<=", ">>="),
                     hasEitherOperand(SignedIntegerOperand),
                     hasLHS(hasType(isInteger())), hasRHS(hasType(isInteger())))
          .bind("binary-sign-interference"),
      this);

  // Match unary operations on signed integer types.
  Finder->addMatcher(
      unaryOperator(hasOperatorName("~"), hasUnaryOperand(SignedIntegerOperand))
          .bind("unary-signed"),
      this);
}

void SignedBitwiseCheck::check(const MatchFinder::MatchResult &Result) {
  const ast_matchers::BoundNodes &N = Result.Nodes;
  const auto *SignedOperand = N.getNodeAs<Expr>("signed-operand");
  assert(SignedOperand &&
         "No signed operand found in problematic bitwise operations");

  bool IsUnary = false;
  SourceLocation Location;

  if (const auto *UnaryOp = N.getNodeAs<UnaryOperator>("unary-signed")) {
    IsUnary = true;
    Location = UnaryOp->getBeginLoc();
  } else {
    if (const auto *BinaryOp =
            N.getNodeAs<BinaryOperator>("binary-no-sign-interference"))
      Location = BinaryOp->getBeginLoc();
    else if (const auto *BinaryOp =
                 N.getNodeAs<BinaryOperator>("binary-sign-interference"))
      Location = BinaryOp->getBeginLoc();
    else
      llvm_unreachable("unexpected matcher result");
  }
  diag(Location, "use of a signed integer operand with a "
                 "%select{binary|unary}0 bitwise operator")
      << IsUnary << SignedOperand->getSourceRange();
}

} // namespace hicpp
} // namespace tidy
} // namespace clang
