// TODO: once the constraint manager is smart enough to handle non simplified // symbolic expressions remove this function. Note that this can not be used in // the constraint manager as is, since this does not handle overflows. It is // safe to assume, however, that memory offsets will not overflow. static std::pair<NonLoc, nonloc::ConcreteInt> getSimplifiedOffsets(NonLoc offset, nonloc::ConcreteInt extent, SValBuilder &svalBuilder) { Optional<nonloc::SymbolVal> SymVal = offset.getAs<nonloc::SymbolVal>(); if (SymVal && SymVal->isExpression()) { if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SymVal->getSymbol())) { llvm::APSInt constant = APSIntType(extent.getValue()).convert(SIE->getRHS()); switch (SIE->getOpcode()) { case BO_Mul: // The constant should never be 0 here, since it the result of scaling // based on the size of a type which is never 0. if ((extent.getValue() % constant) != 0) return std::pair<NonLoc, nonloc::ConcreteInt>(offset, extent); else return getSimplifiedOffsets( nonloc::SymbolVal(SIE->getLHS()), svalBuilder.makeIntVal(extent.getValue() / constant), svalBuilder); case BO_Add: return getSimplifiedOffsets( nonloc::SymbolVal(SIE->getLHS()), svalBuilder.makeIntVal(extent.getValue() - constant), svalBuilder); default: break; } } } return std::pair<NonLoc, nonloc::ConcreteInt>(offset, extent); }
SVal nonloc::ConcreteInt::evalBinOp(ValueManager &ValMgr, BinaryOperator::Opcode Op, const nonloc::ConcreteInt& R) const { const llvm::APSInt* X = ValMgr.getBasicValueFactory().EvaluateAPSInt(Op, getValue(), R.getValue()); if (X) return nonloc::ConcreteInt(*X); else return UndefinedVal(); }
SVal nonloc::ConcreteInt::evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op, const nonloc::ConcreteInt& R) const { const llvm::APSInt* X = svalBuilder.getBasicValueFactory().evalAPSInt(Op, getValue(), R.getValue()); if (X) return nonloc::ConcreteInt(*X); else return UndefinedVal(); }
SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, const nonloc::ConcreteInt& R) const { const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue()); if (X) return nonloc::ConcreteInt(*X); else return UndefinedVal(); }