ProgramStateRef SimpleConstraintManager::assumeInclusiveRange( ProgramStateRef State, NonLoc Value, const llvm::APSInt &From, const llvm::APSInt &To, bool InRange) { assert(From.isUnsigned() == To.isUnsigned() && From.getBitWidth() == To.getBitWidth() && "Values should have same types!"); if (!canReasonAbout(Value)) { // Just add the constraint to the expression without trying to simplify. SymbolRef Sym = Value.getAsSymExpr(); assert(Sym); return assumeSymWithinInclusiveRange(State, Sym, From, To, InRange); } switch (Value.getSubKind()) { default: llvm_unreachable("'assumeInclusiveRange' is not implemented" "for this NonLoc"); case nonloc::LocAsIntegerKind: case nonloc::SymbolValKind: { if (SymbolRef Sym = Value.getAsSymbol()) return assumeSymWithinInclusiveRange(State, Sym, From, To, InRange); return State; } // end switch case nonloc::ConcreteIntKind: { const llvm::APSInt &IntVal = Value.castAs<nonloc::ConcreteInt>().getValue(); bool IsInRange = IntVal >= From && IntVal <= To; bool isFeasible = (IsInRange == InRange); return isFeasible ? State : nullptr; } } // end switch }
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); }