//== IdenticalExprChecker.cpp - Identical expression checker----------------==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This defines IdenticalExprChecker, a check that warns about
/// unintended use of identical expressions.
///
/// It checks for use of identical expressions with comparison operators and
/// inside conditional expressions.
///
//===----------------------------------------------------------------------===//

#include "ClangSACheckers.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"

using namespace clang;
using namespace ento;

static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1,
                            const Stmt *Stmt2, bool IgnoreSideEffects = false);
//===----------------------------------------------------------------------===//
// FindIdenticalExprVisitor - Identify nodes using identical expressions.
//===----------------------------------------------------------------------===//

namespace {
class FindIdenticalExprVisitor
    : public RecursiveASTVisitor<FindIdenticalExprVisitor> {
  BugReporter &BR;
  const CheckerBase *Checker;
  AnalysisDeclContext *AC;
public:
  explicit FindIdenticalExprVisitor(BugReporter &B,
                                    const CheckerBase *Checker,
                                    AnalysisDeclContext *A)
      : BR(B), Checker(Checker), AC(A) {}
  // FindIdenticalExprVisitor only visits nodes
  // that are binary operators, if statements or
  // conditional operators.
  bool VisitBinaryOperator(const BinaryOperator *B);
  bool VisitIfStmt(const IfStmt *I);
  bool VisitConditionalOperator(const ConditionalOperator *C);

private:
  void reportIdenticalExpr(const BinaryOperator *B, bool CheckBitwise,
                           ArrayRef<SourceRange> Sr);
  void checkBitwiseOrLogicalOp(const BinaryOperator *B, bool CheckBitwise);
  void checkComparisonOp(const BinaryOperator *B);
};
} // end anonymous namespace

void FindIdenticalExprVisitor::reportIdenticalExpr(const BinaryOperator *B,
                                                   bool CheckBitwise,
                                                   ArrayRef<SourceRange> Sr) {
  StringRef Message;
  if (CheckBitwise)
    Message = "identical expressions on both sides of bitwise operator";
  else
    Message = "identical expressions on both sides of logical operator";

  PathDiagnosticLocation ELoc =
      PathDiagnosticLocation::createOperatorLoc(B, BR.getSourceManager());
  BR.EmitBasicReport(AC->getDecl(), Checker,
                     "Use of identical expressions",
                     categories::LogicError,
                     Message, ELoc, Sr);
}

void FindIdenticalExprVisitor::checkBitwiseOrLogicalOp(const BinaryOperator *B,
                                                       bool CheckBitwise) {
  SourceRange Sr[2];

  const Expr *LHS = B->getLHS();
  const Expr *RHS = B->getRHS();

  // Split operators as long as we still have operators to split on. We will
  // get called for every binary operator in an expression so there is no need
  // to check every one against each other here, just the right most one with
  // the others.
  while (const BinaryOperator *B2 = dyn_cast<BinaryOperator>(LHS)) {
    if (B->getOpcode() != B2->getOpcode())
      break;
    if (isIdenticalStmt(AC->getASTContext(), RHS, B2->getRHS())) {
      Sr[0] = RHS->getSourceRange();
      Sr[1] = B2->getRHS()->getSourceRange();
      reportIdenticalExpr(B, CheckBitwise, Sr);
    }
    LHS = B2->getLHS();
  }

  if (isIdenticalStmt(AC->getASTContext(), RHS, LHS)) {
    Sr[0] = RHS->getSourceRange();
    Sr[1] = LHS->getSourceRange();
    reportIdenticalExpr(B, CheckBitwise, Sr);
  }
}

bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) {
  const Stmt *Stmt1 = I->getThen();
  const Stmt *Stmt2 = I->getElse();

  // Check for identical inner condition:
  //
  // if (x<10) {
  //   if (x<10) {
  //   ..
  if (const CompoundStmt *CS = dyn_cast<CompoundStmt>(Stmt1)) {
    if (!CS->body_empty()) {
      const IfStmt *InnerIf = dyn_cast<IfStmt>(*CS->body_begin());
      if (InnerIf && isIdenticalStmt(AC->getASTContext(), I->getCond(), InnerIf->getCond(), /*ignoreSideEffects=*/ false)) {
        PathDiagnosticLocation ELoc(InnerIf->getCond(), BR.getSourceManager(), AC);
        BR.EmitBasicReport(AC->getDecl(), Checker, "Identical conditions",
          categories::LogicError,
          "conditions of the inner and outer statements are identical",
          ELoc);
      }
    }
  }

  // Check for identical conditions:
  //
  // if (b) {
  //   foo1();
  // } else if (b) {
  //   foo2();
  // }
  if (Stmt1 && Stmt2) {
    const Expr *Cond1 = I->getCond();
    const Stmt *Else = Stmt2;
    while (const IfStmt *I2 = dyn_cast_or_null<IfStmt>(Else)) {
      const Expr *Cond2 = I2->getCond();
      if (isIdenticalStmt(AC->getASTContext(), Cond1, Cond2, false)) {
        SourceRange Sr = Cond1->getSourceRange();
        PathDiagnosticLocation ELoc(Cond2, BR.getSourceManager(), AC);
        BR.EmitBasicReport(AC->getDecl(), Checker, "Identical conditions",
                           categories::LogicError,
                           "expression is identical to previous condition",
                           ELoc, Sr);
      }
      Else = I2->getElse();
    }
  }

  if (!Stmt1 || !Stmt2)
    return true;

  // Special handling for code like:
  //
  // if (b) {
  //   i = 1;
  // } else
  //   i = 1;
  if (const CompoundStmt *CompStmt = dyn_cast<CompoundStmt>(Stmt1)) {
    if (CompStmt->size() == 1)
      Stmt1 = CompStmt->body_back();
  }
  if (const CompoundStmt *CompStmt = dyn_cast<CompoundStmt>(Stmt2)) {
    if (CompStmt->size() == 1)
      Stmt2 = CompStmt->body_back();
  }

  if (isIdenticalStmt(AC->getASTContext(), Stmt1, Stmt2, true)) {
      PathDiagnosticLocation ELoc =
          PathDiagnosticLocation::createBegin(I, BR.getSourceManager(), AC);
      BR.EmitBasicReport(AC->getDecl(), Checker,
                         "Identical branches",
                         categories::LogicError,
                         "true and false branches are identical", ELoc);
  }
  return true;
}

bool FindIdenticalExprVisitor::VisitBinaryOperator(const BinaryOperator *B) {
  BinaryOperator::Opcode Op = B->getOpcode();

  if (BinaryOperator::isBitwiseOp(Op))
    checkBitwiseOrLogicalOp(B, true);

  if (BinaryOperator::isLogicalOp(Op))
    checkBitwiseOrLogicalOp(B, false);

  if (BinaryOperator::isComparisonOp(Op))
    checkComparisonOp(B);

  // We want to visit ALL nodes (subexpressions of binary comparison
  // expressions too) that contains comparison operators.
  // True is always returned to traverse ALL nodes.
  return true;
}

void FindIdenticalExprVisitor::checkComparisonOp(const BinaryOperator *B) {
  BinaryOperator::Opcode Op = B->getOpcode();

  //
  // Special case for floating-point representation.
  //
  // If expressions on both sides of comparison operator are of type float,
  // then for some comparison operators no warning shall be
  // reported even if the expressions are identical from a symbolic point of
  // view. Comparison between expressions, declared variables and literals
  // are treated differently.
  //
  // != and == between float literals that have the same value should NOT warn.
  // < > between float literals that have the same value SHOULD warn.
  //
  // != and == between the same float declaration should NOT warn.
  // < > between the same float declaration SHOULD warn.
  //
  // != and == between eq. expressions that evaluates into float
  //           should NOT warn.
  // < >       between eq. expressions that evaluates into float
  //           should NOT warn.
  //
  const Expr *LHS = B->getLHS()->IgnoreParenImpCasts();
  const Expr *RHS = B->getRHS()->IgnoreParenImpCasts();

  const DeclRefExpr *DeclRef1 = dyn_cast<DeclRefExpr>(LHS);
  const DeclRefExpr *DeclRef2 = dyn_cast<DeclRefExpr>(RHS);
  const FloatingLiteral *FloatLit1 = dyn_cast<FloatingLiteral>(LHS);
  const FloatingLiteral *FloatLit2 = dyn_cast<FloatingLiteral>(RHS);
  if ((DeclRef1) && (DeclRef2)) {
    if ((DeclRef1->getType()->hasFloatingRepresentation()) &&
        (DeclRef2->getType()->hasFloatingRepresentation())) {
      if (DeclRef1->getDecl() == DeclRef2->getDecl()) {
        if ((Op == BO_EQ) || (Op == BO_NE)) {
          return;
        }
      }
    }
  } else if ((FloatLit1) && (FloatLit2)) {
    if (FloatLit1->getValue().bitwiseIsEqual(FloatLit2->getValue())) {
      if ((Op == BO_EQ) || (Op == BO_NE)) {
        return;
      }
    }
  } else if (LHS->getType()->hasFloatingRepresentation()) {
    // If any side of comparison operator still has floating-point
    // representation, then it's an expression. Don't warn.
    // Here only LHS is checked since RHS will be implicit casted to float.
    return;
  } else {
    // No special case with floating-point representation, report as usual.
  }

  if (isIdenticalStmt(AC->getASTContext(), B->getLHS(), B->getRHS())) {
    PathDiagnosticLocation ELoc =
        PathDiagnosticLocation::createOperatorLoc(B, BR.getSourceManager());
    StringRef Message;
    if (((Op == BO_EQ) || (Op == BO_LE) || (Op == BO_GE)))
      Message = "comparison of identical expressions always evaluates to true";
    else
      Message = "comparison of identical expressions always evaluates to false";
    BR.EmitBasicReport(AC->getDecl(), Checker,
                       "Compare of identical expressions",
                       categories::LogicError, Message, ELoc);
  }
}

bool FindIdenticalExprVisitor::VisitConditionalOperator(
    const ConditionalOperator *C) {

  // Check if expressions in conditional expression are identical
  // from a symbolic point of view.

  if (isIdenticalStmt(AC->getASTContext(), C->getTrueExpr(),
                      C->getFalseExpr(), true)) {
    PathDiagnosticLocation ELoc =
        PathDiagnosticLocation::createConditionalColonLoc(
            C, BR.getSourceManager());

    SourceRange Sr[2];
    Sr[0] = C->getTrueExpr()->getSourceRange();
    Sr[1] = C->getFalseExpr()->getSourceRange();
    BR.EmitBasicReport(
        AC->getDecl(), Checker,
        "Identical expressions in conditional expression",
        categories::LogicError,
        "identical expressions on both sides of ':' in conditional expression",
        ELoc, Sr);
  }
  // We want to visit ALL nodes (expressions in conditional
  // expressions too) that contains conditional operators,
  // thus always return true to traverse ALL nodes.
  return true;
}

/// \brief Determines whether two statement trees are identical regarding
/// operators and symbols.
///
/// Exceptions: expressions containing macros or functions with possible side
/// effects are never considered identical.
/// Limitations: (t + u) and (u + t) are not considered identical.
/// t*(u + t) and t*u + t*t are not considered identical.
///
static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1,
                            const Stmt *Stmt2, bool IgnoreSideEffects) {

  if (!Stmt1 || !Stmt2) {
    return !Stmt1 && !Stmt2;
  }

  // If Stmt1 & Stmt2 are of different class then they are not
  // identical statements.
  if (Stmt1->getStmtClass() != Stmt2->getStmtClass())
    return false;

  const Expr *Expr1 = dyn_cast<Expr>(Stmt1);
  const Expr *Expr2 = dyn_cast<Expr>(Stmt2);

  if (Expr1 && Expr2) {
    // If Stmt1 has side effects then don't warn even if expressions
    // are identical.
    if (!IgnoreSideEffects && Expr1->HasSideEffects(Ctx))
      return false;
    // If either expression comes from a macro then don't warn even if
    // the expressions are identical.
    if ((Expr1->getExprLoc().isMacroID()) || (Expr2->getExprLoc().isMacroID()))
      return false;

    // If all children of two expressions are identical, return true.
    Expr::const_child_iterator I1 = Expr1->child_begin();
    Expr::const_child_iterator I2 = Expr2->child_begin();
    while (I1 != Expr1->child_end() && I2 != Expr2->child_end()) {
      if (!*I1 || !*I2 || !isIdenticalStmt(Ctx, *I1, *I2, IgnoreSideEffects))
        return false;
      ++I1;
      ++I2;
    }
    // If there are different number of children in the statements, return
    // false.
    if (I1 != Expr1->child_end())
      return false;
    if (I2 != Expr2->child_end())
      return false;
  }

  switch (Stmt1->getStmtClass()) {
  default:
    return false;
  case Stmt::CallExprClass:
  case Stmt::ArraySubscriptExprClass:
  case Stmt::OMPArraySectionExprClass:
  case Stmt::ImplicitCastExprClass:
  case Stmt::ParenExprClass:
  case Stmt::BreakStmtClass:
  case Stmt::ContinueStmtClass:
  case Stmt::NullStmtClass:
    return true;
  case Stmt::CStyleCastExprClass: {
    const CStyleCastExpr* CastExpr1 = cast<CStyleCastExpr>(Stmt1);
    const CStyleCastExpr* CastExpr2 = cast<CStyleCastExpr>(Stmt2);

    return CastExpr1->getTypeAsWritten() == CastExpr2->getTypeAsWritten();
  }
  case Stmt::ReturnStmtClass: {
    const ReturnStmt *ReturnStmt1 = cast<ReturnStmt>(Stmt1);
    const ReturnStmt *ReturnStmt2 = cast<ReturnStmt>(Stmt2);

    return isIdenticalStmt(Ctx, ReturnStmt1->getRetValue(),
                           ReturnStmt2->getRetValue(), IgnoreSideEffects);
  }
  case Stmt::ForStmtClass: {
    const ForStmt *ForStmt1 = cast<ForStmt>(Stmt1);
    const ForStmt *ForStmt2 = cast<ForStmt>(Stmt2);

    if (!isIdenticalStmt(Ctx, ForStmt1->getInit(), ForStmt2->getInit(),
                         IgnoreSideEffects))
      return false;
    if (!isIdenticalStmt(Ctx, ForStmt1->getCond(), ForStmt2->getCond(),
                         IgnoreSideEffects))
      return false;
    if (!isIdenticalStmt(Ctx, ForStmt1->getInc(), ForStmt2->getInc(),
                         IgnoreSideEffects))
      return false;
    if (!isIdenticalStmt(Ctx, ForStmt1->getBody(), ForStmt2->getBody(),
                         IgnoreSideEffects))
      return false;
    return true;
  }
  case Stmt::DoStmtClass: {
    const DoStmt *DStmt1 = cast<DoStmt>(Stmt1);
    const DoStmt *DStmt2 = cast<DoStmt>(Stmt2);

    if (!isIdenticalStmt(Ctx, DStmt1->getCond(), DStmt2->getCond(),
                         IgnoreSideEffects))
      return false;
    if (!isIdenticalStmt(Ctx, DStmt1->getBody(), DStmt2->getBody(),
                         IgnoreSideEffects))
      return false;
    return true;
  }
  case Stmt::WhileStmtClass: {
    const WhileStmt *WStmt1 = cast<WhileStmt>(Stmt1);
    const WhileStmt *WStmt2 = cast<WhileStmt>(Stmt2);

    if (!isIdenticalStmt(Ctx, WStmt1->getCond(), WStmt2->getCond(),
                         IgnoreSideEffects))
      return false;
    if (!isIdenticalStmt(Ctx, WStmt1->getBody(), WStmt2->getBody(),
                         IgnoreSideEffects))
      return false;
    return true;
  }
  case Stmt::IfStmtClass: {
    const IfStmt *IStmt1 = cast<IfStmt>(Stmt1);
    const IfStmt *IStmt2 = cast<IfStmt>(Stmt2);

    if (!isIdenticalStmt(Ctx, IStmt1->getCond(), IStmt2->getCond(),
                         IgnoreSideEffects))
      return false;
    if (!isIdenticalStmt(Ctx, IStmt1->getThen(), IStmt2->getThen(),
                         IgnoreSideEffects))
      return false;
    if (!isIdenticalStmt(Ctx, IStmt1->getElse(), IStmt2->getElse(),
                         IgnoreSideEffects))
      return false;
    return true;
  }
  case Stmt::CompoundStmtClass: {
    const CompoundStmt *CompStmt1 = cast<CompoundStmt>(Stmt1);
    const CompoundStmt *CompStmt2 = cast<CompoundStmt>(Stmt2);

    if (CompStmt1->size() != CompStmt2->size())
      return false;

    CompoundStmt::const_body_iterator I1 = CompStmt1->body_begin();
    CompoundStmt::const_body_iterator I2 = CompStmt2->body_begin();
    while (I1 != CompStmt1->body_end() && I2 != CompStmt2->body_end()) {
      if (!isIdenticalStmt(Ctx, *I1, *I2, IgnoreSideEffects))
        return false;
      ++I1;
      ++I2;
    }

    return true;
  }
  case Stmt::CompoundAssignOperatorClass:
  case Stmt::BinaryOperatorClass: {
    const BinaryOperator *BinOp1 = cast<BinaryOperator>(Stmt1);
    const BinaryOperator *BinOp2 = cast<BinaryOperator>(Stmt2);
    return BinOp1->getOpcode() == BinOp2->getOpcode();
  }
  case Stmt::CharacterLiteralClass: {
    const CharacterLiteral *CharLit1 = cast<CharacterLiteral>(Stmt1);
    const CharacterLiteral *CharLit2 = cast<CharacterLiteral>(Stmt2);
    return CharLit1->getValue() == CharLit2->getValue();
  }
  case Stmt::DeclRefExprClass: {
    const DeclRefExpr *DeclRef1 = cast<DeclRefExpr>(Stmt1);
    const DeclRefExpr *DeclRef2 = cast<DeclRefExpr>(Stmt2);
    return DeclRef1->getDecl() == DeclRef2->getDecl();
  }
  case Stmt::IntegerLiteralClass: {
    const IntegerLiteral *IntLit1 = cast<IntegerLiteral>(Stmt1);
    const IntegerLiteral *IntLit2 = cast<IntegerLiteral>(Stmt2);

    llvm::APInt I1 = IntLit1->getValue();
    llvm::APInt I2 = IntLit2->getValue();
    if (I1.getBitWidth() != I2.getBitWidth())
      return false;
    return  I1 == I2;
  }
  case Stmt::FloatingLiteralClass: {
    const FloatingLiteral *FloatLit1 = cast<FloatingLiteral>(Stmt1);
    const FloatingLiteral *FloatLit2 = cast<FloatingLiteral>(Stmt2);
    return FloatLit1->getValue().bitwiseIsEqual(FloatLit2->getValue());
  }
  case Stmt::StringLiteralClass: {
    const StringLiteral *StringLit1 = cast<StringLiteral>(Stmt1);
    const StringLiteral *StringLit2 = cast<StringLiteral>(Stmt2);
    return StringLit1->getBytes() == StringLit2->getBytes();
  }
  case Stmt::MemberExprClass: {
    const MemberExpr *MemberStmt1 = cast<MemberExpr>(Stmt1);
    const MemberExpr *MemberStmt2 = cast<MemberExpr>(Stmt2);
    return MemberStmt1->getMemberDecl() == MemberStmt2->getMemberDecl();
  }
  case Stmt::UnaryOperatorClass: {
    const UnaryOperator *UnaryOp1 = cast<UnaryOperator>(Stmt1);
    const UnaryOperator *UnaryOp2 = cast<UnaryOperator>(Stmt2);
    return UnaryOp1->getOpcode() == UnaryOp2->getOpcode();
  }
  }
}

//===----------------------------------------------------------------------===//
// FindIdenticalExprChecker
//===----------------------------------------------------------------------===//

namespace {
class FindIdenticalExprChecker : public Checker<check::ASTCodeBody> {
public:
  void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr,
                        BugReporter &BR) const {
    FindIdenticalExprVisitor Visitor(BR, this, Mgr.getAnalysisDeclContext(D));
    Visitor.TraverseDecl(const_cast<Decl *>(D));
  }
};
} // end anonymous namespace

void ento::registerIdenticalExprChecker(CheckerManager &Mgr) {
  Mgr.registerChecker<FindIdenticalExprChecker>();
}
