//== RangedConstraintManager.cpp --------------------------------*- C++ -*--==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines RangedConstraintManager, a class that provides a
//  range-based constraint manager interface.
//
//===----------------------------------------------------------------------===//

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

namespace clang {

namespace ento {

RangedConstraintManager::~RangedConstraintManager() {}

ProgramStateRef RangedConstraintManager::assumeSym(ProgramStateRef State,
                                                   SymbolRef Sym,
                                                   bool Assumption) {
  // Handle SymbolData.
  if (isa<SymbolData>(Sym)) {
    return assumeSymUnsupported(State, Sym, Assumption);

    // Handle symbolic expression.
  } else 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)) {
      if (!Assumption)
        op = BinaryOperator::negateComparisonOp(op);

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

  } else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) {
    // 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();
    BinaryOperator::Opcode Op = SSE->getOpcode();
    assert(BinaryOperator::isComparisonOp(Op));

    // For now, we only support comparing pointers.
    assert(Loc::isLocType(SSE->getLHS()->getType()));
    assert(Loc::isLocType(SSE->getRHS()->getType()));
    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 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) {
  // 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) {
  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;
    }
  }
}

} // end of namespace ento

} // end of namespace clang
