//== RangedConstraintManager.cpp --------------------------------*- C++ -*--==//
//
// 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
//
//===----------------------------------------------------------------------===//
//
//  This file defines RangedConstraintManager, a class that provides a
//  range-based constraint manager interface.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"

namespace clang {

namespace ento {

RangedConstraintManager::~RangedConstraintManager() {}

ProgramStateRef RangedConstraintManager::assumeSym(ProgramStateRef State,
                                                   SymbolRef Sym,
                                                   bool Assumption) {
  Sym = simplify(State, Sym);

  // Handle SymbolData.
  if (isa<SymbolData>(Sym))
    return assumeSymUnsupported(State, Sym, Assumption);

  // Handle symbolic expression.
  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(Sym)) {
    // We can only simplify expressions whose RHS is an integer.

    BinaryOperator::Opcode op = SIE->getOpcode();
    if (BinaryOperator::isComparisonOp(op) && op != BO_Cmp) {
      if (!Assumption)
        op = BinaryOperator::negateComparisonOp(op);

      return assumeSymRel(State, SIE->getLHS(), op, SIE->getRHS());
    }

    // Handle adjustment with non-comparison ops.
    const llvm::APSInt &Zero = getBasicVals().getValue(0, SIE->getType());
    return assumeSymRel(State, SIE, (Assumption ? BO_NE : BO_EQ), Zero);
  }

  if (const auto *SSE = dyn_cast<SymSymExpr>(Sym)) {
    BinaryOperator::Opcode Op = SSE->getOpcode();
    assert(BinaryOperator::isComparisonOp(Op));

    // We convert equality operations for pointers only.
    if (Loc::isLocType(SSE->getLHS()->getType()) &&
        Loc::isLocType(SSE->getRHS()->getType())) {
      // Translate "a != b" to "(b - a) != 0".
      // We invert the order of the operands as a heuristic for how loop
      // conditions are usually written ("begin != end") as compared to length
      // calculations ("end - begin"). The more correct thing to do would be to
      // canonicalize "a - b" and "b - a", which would allow us to treat
      // "a != b" and "b != a" the same.

      SymbolManager &SymMgr = getSymbolManager();
      QualType DiffTy = SymMgr.getContext().getPointerDiffType();
      SymbolRef Subtraction =
          SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub, SSE->getLHS(), DiffTy);

      const llvm::APSInt &Zero = getBasicVals().getValue(0, DiffTy);
      Op = BinaryOperator::reverseComparisonOp(Op);
      if (!Assumption)
        Op = BinaryOperator::negateComparisonOp(Op);
      return assumeSymRel(State, Subtraction, Op, Zero);
    }

    if (BinaryOperator::isEqualityOp(Op)) {
      SymbolManager &SymMgr = getSymbolManager();

      QualType ExprType = SSE->getType();
      SymbolRef CanonicalEquality =
          SymMgr.getSymSymExpr(SSE->getLHS(), BO_EQ, SSE->getRHS(), ExprType);

      bool WasEqual = SSE->getOpcode() == BO_EQ;
      bool IsExpectedEqual = WasEqual == Assumption;

      const llvm::APSInt &Zero = getBasicVals().getValue(0, ExprType);

      if (IsExpectedEqual) {
        return assumeSymNE(State, CanonicalEquality, Zero, Zero);
      }

      return assumeSymEQ(State, CanonicalEquality, Zero, Zero);
    }
  }

  // If we get here, there's nothing else we can do but treat the symbol as
  // opaque.
  return assumeSymUnsupported(State, Sym, Assumption);
}

ProgramStateRef RangedConstraintManager::assumeSymInclusiveRange(
    ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
    const llvm::APSInt &To, bool InRange) {

  Sym = simplify(State, Sym);

  // Get the type used for calculating wraparound.
  BasicValueFactory &BVF = getBasicVals();
  APSIntType WraparoundType = BVF.getAPSIntType(Sym->getType());

  llvm::APSInt Adjustment = WraparoundType.getZeroValue();
  SymbolRef AdjustedSym = Sym;
  computeAdjustment(AdjustedSym, Adjustment);

  // Convert the right-hand side integer as necessary.
  APSIntType ComparisonType = std::max(WraparoundType, APSIntType(From));
  llvm::APSInt ConvertedFrom = ComparisonType.convert(From);
  llvm::APSInt ConvertedTo = ComparisonType.convert(To);

  // Prefer unsigned comparisons.
  if (ComparisonType.getBitWidth() == WraparoundType.getBitWidth() &&
      ComparisonType.isUnsigned() && !WraparoundType.isUnsigned())
    Adjustment.setIsSigned(false);

  if (InRange)
    return assumeSymWithinInclusiveRange(State, AdjustedSym, ConvertedFrom,
                                         ConvertedTo, Adjustment);
  return assumeSymOutsideInclusiveRange(State, AdjustedSym, ConvertedFrom,
                                        ConvertedTo, Adjustment);
}

ProgramStateRef
RangedConstraintManager::assumeSymUnsupported(ProgramStateRef State,
                                              SymbolRef Sym, bool Assumption) {
  Sym = simplify(State, Sym);

  BasicValueFactory &BVF = getBasicVals();
  QualType T = Sym->getType();

  // Non-integer types are not supported.
  if (!T->isIntegralOrEnumerationType())
    return State;

  // Reverse the operation and add directly to state.
  const llvm::APSInt &Zero = BVF.getValue(0, T);
  if (Assumption)
    return assumeSymNE(State, Sym, Zero, Zero);
  else
    return assumeSymEQ(State, Sym, Zero, Zero);
}

ProgramStateRef RangedConstraintManager::assumeSymRel(ProgramStateRef State,
                                                      SymbolRef Sym,
                                                      BinaryOperator::Opcode Op,
                                                      const llvm::APSInt &Int) {
  assert(BinaryOperator::isComparisonOp(Op) &&
         "Non-comparison ops should be rewritten as comparisons to zero.");

  // Simplification: translate an assume of a constraint of the form
  // "(exp comparison_op expr) != 0" to true into an assume of
  // "exp comparison_op expr" to true. (And similarly, an assume of the form
  // "(exp comparison_op expr) == 0" to true into an assume of
  // "exp comparison_op expr" to false.)
  if (Int == 0 && (Op == BO_EQ || Op == BO_NE)) {
    if (const BinarySymExpr *SE = dyn_cast<BinarySymExpr>(Sym))
      if (BinaryOperator::isComparisonOp(SE->getOpcode()))
        return assumeSym(State, Sym, (Op == BO_NE ? true : false));
  }

  // Get the type used for calculating wraparound.
  BasicValueFactory &BVF = getBasicVals();
  APSIntType WraparoundType = BVF.getAPSIntType(Sym->getType());

  // We only handle simple comparisons of the form "$sym == constant"
  // or "($sym+constant1) == constant2".
  // The adjustment is "constant1" in the above expression. It's used to
  // "slide" the solution range around for modular arithmetic. For example,
  // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
  // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
  // the subclasses of SimpleConstraintManager to handle the adjustment.
  llvm::APSInt Adjustment = WraparoundType.getZeroValue();
  computeAdjustment(Sym, Adjustment);

  // Convert the right-hand side integer as necessary.
  APSIntType ComparisonType = std::max(WraparoundType, APSIntType(Int));
  llvm::APSInt ConvertedInt = ComparisonType.convert(Int);

  // Prefer unsigned comparisons.
  if (ComparisonType.getBitWidth() == WraparoundType.getBitWidth() &&
      ComparisonType.isUnsigned() && !WraparoundType.isUnsigned())
    Adjustment.setIsSigned(false);

  switch (Op) {
  default:
    llvm_unreachable("invalid operation not caught by assertion above");

  case BO_EQ:
    return assumeSymEQ(State, Sym, ConvertedInt, Adjustment);

  case BO_NE:
    return assumeSymNE(State, Sym, ConvertedInt, Adjustment);

  case BO_GT:
    return assumeSymGT(State, Sym, ConvertedInt, Adjustment);

  case BO_GE:
    return assumeSymGE(State, Sym, ConvertedInt, Adjustment);

  case BO_LT:
    return assumeSymLT(State, Sym, ConvertedInt, Adjustment);

  case BO_LE:
    return assumeSymLE(State, Sym, ConvertedInt, Adjustment);
  } // end switch
}

void RangedConstraintManager::computeAdjustment(SymbolRef &Sym,
                                                llvm::APSInt &Adjustment) {
  // Is it a "($sym+constant1)" expression?
  if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(Sym)) {
    BinaryOperator::Opcode Op = SE->getOpcode();
    if (Op == BO_Add || Op == BO_Sub) {
      Sym = SE->getLHS();
      Adjustment = APSIntType(Adjustment).convert(SE->getRHS());

      // Don't forget to negate the adjustment if it's being subtracted.
      // This should happen /after/ promotion, in case the value being
      // subtracted is, say, CHAR_MIN, and the promoted type is 'int'.
      if (Op == BO_Sub)
        Adjustment = -Adjustment;
    }
  }
}

SVal simplifyToSVal(ProgramStateRef State, SymbolRef Sym) {
  SValBuilder &SVB = State->getStateManager().getSValBuilder();
  return SVB.simplifySVal(State, SVB.makeSymbolVal(Sym));
}

SymbolRef simplify(ProgramStateRef State, SymbolRef Sym) {
  SVal SimplifiedVal = simplifyToSVal(State, Sym);
  if (SymbolRef SimplifiedSym = SimplifiedVal.getAsSymbol())
    return SimplifiedSym;
  return Sym;
}

} // end of namespace ento
} // end of namespace clang
