//== 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();
    if (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.acquire<SymSymExpr>(
            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.acquire<SymSymExpr>(
            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
