// Turn all [A, B] ranges to [-B, -A]. Ranges [MIN, B] are turned to range set // [MIN, MIN] U [-B, MAX], when MIN and MAX are the minimal and the maximal // signed values of the type. RangeSet RangeSet::Negate(BasicValueFactory &BV, Factory &F) const { PrimRangeSet newRanges = F.getEmptySet(); for (iterator i = begin(), e = end(); i != e; ++i) { const llvm::APSInt &from = i->From(), &to = i->To(); const llvm::APSInt &newTo = (from.isMinSignedValue() ? BV.getMaxValue(from) : BV.getValue(- from)); if (to.isMaxSignedValue() && !newRanges.isEmpty() && newRanges.begin()->From().isMinSignedValue()) { assert(newRanges.begin()->To().isMinSignedValue() && "Ranges should not overlap"); assert(!from.isMinSignedValue() && "Ranges should not overlap"); const llvm::APSInt &newFrom = newRanges.begin()->From(); newRanges = F.add(F.remove(newRanges, *newRanges.begin()), Range(newFrom, newTo)); } else if (!to.isMinSignedValue()) { const llvm::APSInt &newFrom = BV.getValue(- to); newRanges = F.add(newRanges, Range(newFrom, newTo)); } if (from.isMinSignedValue()) { newRanges = F.add(newRanges, Range(BV.getMinValue(from), BV.getMinValue(from))); } } return newRanges; }
/// Apply implicit constraints for bitwise OR- and AND-. /// For unsigned types, bitwise OR with a constant always returns /// a value greater-or-equal than the constant, and bitwise AND /// returns a value less-or-equal then the constant. /// /// Pattern matches the expression \p Sym against those rule, /// and applies the required constraints. /// \p Input Previously established expression range set static RangeSet applyBitwiseConstraints( BasicValueFactory &BV, RangeSet::Factory &F, RangeSet Input, const SymIntExpr* SIE) { QualType T = SIE->getType(); bool IsUnsigned = T->isUnsignedIntegerType(); const llvm::APSInt &RHS = SIE->getRHS(); const llvm::APSInt &Zero = BV.getAPSIntType(T).getZeroValue(); BinaryOperator::Opcode Operator = SIE->getOpcode(); // For unsigned types, the output of bitwise-or is bigger-or-equal than RHS. if (Operator == BO_Or && IsUnsigned) return Input.Intersect(BV, F, RHS, BV.getMaxValue(T)); // Bitwise-or with a non-zero constant is always non-zero. if (Operator == BO_Or && RHS != Zero) return assumeNonZero(BV, F, SIE, Input); // For unsigned types, or positive RHS, // bitwise-and output is always smaller-or-equal than RHS (assuming two's // complement representation of signed types). if (Operator == BO_And && (IsUnsigned || RHS >= Zero)) return Input.Intersect(BV, F, BV.getMinValue(T), RHS); return Input; }
/// Return a range set subtracting zero from \p Domain. static RangeSet assumeNonZero( BasicValueFactory &BV, RangeSet::Factory &F, SymbolRef Sym, RangeSet Domain) { APSIntType IntType = BV.getAPSIntType(Sym->getType()); return Domain.Intersect(BV, F, ++IntType.getZeroValue(), --IntType.getZeroValue()); }
// Returns a set containing the values in the receiving set, intersected with // the closed range [Lower, Upper]. Unlike the Range type, this range uses // modular arithmetic, corresponding to the common treatment of C integer // overflow. Thus, if the Lower bound is greater than the Upper bound, the // range is taken to wrap around. This is equivalent to taking the // intersection with the two ranges [Min, Upper] and [Lower, Max], // or, alternatively, /removing/ all integers between Upper and Lower. RangeSet RangeSet::Intersect(BasicValueFactory &BV, Factory &F, llvm::APSInt Lower, llvm::APSInt Upper) const { if (!pin(Lower, Upper)) return F.getEmptySet(); PrimRangeSet newRanges = F.getEmptySet(); PrimRangeSet::iterator i = begin(), e = end(); if (Lower <= Upper) IntersectInRange(BV, F, Lower, Upper, newRanges, i, e); else { // The order of the next two statements is important! // IntersectInRange() does not reset the iteration state for i and e. // Therefore, the lower range most be handled first. IntersectInRange(BV, F, BV.getMinValue(Upper), Upper, newRanges, i, e); IntersectInRange(BV, F, Lower, BV.getMaxValue(Lower), newRanges, i, e); } return newRanges; }
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(); }
/// AddNE - Create a new RangeSet with the additional constraint that the /// value be not be equal to V. RangeSet AddNE(BasicValueFactory &BV, Factory &F, const llvm::APSInt &V) { PrimRangeSet newRanges = ranges; // FIXME: We can perhaps enhance ImmutableSet to do this search for us // in log(N) time using the sorted property of the internal AVL tree. for (iterator i = begin(), e = end(); i != e; ++i) { if (i->Includes(V)) { // Remove the old range. newRanges = F.Remove(newRanges, *i); // Split the old range into possibly one or two ranges. if (V != i->From()) newRanges = F.Add(newRanges, Range(i->From(), BV.Sub1(V))); if (V != i->To()) newRanges = F.Add(newRanges, Range(BV.Add1(V), i->To())); // All of the ranges are non-overlapping, so we can stop. break; } } return newRanges; }
RangeSet AddGT(BasicValueFactory &BV, Factory &F, const llvm::APSInt &V) { PrimRangeSet newRanges = F.GetEmptySet(); for (PrimRangeSet::iterator i = begin(), e = end(); i != e; ++i) { if (i->Includes(V) && i->To() > V) newRanges = F.Add(newRanges, Range(BV.Add1(V), i->To())); else if (i->From() > V) newRanges = F.Add(newRanges, *i); } return newRanges; }
SVal loc::ConcreteInt::evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, const loc::ConcreteInt& R) const { assert(BinaryOperator::isComparisonOp(Op) || Op == BO_Sub); const llvm::APSInt *X = BasicVals.evalAPSInt(Op, getValue(), R.getValue()); if (X) return nonloc::ConcreteInt(*X); else return UndefinedVal(); }
SVal loc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, const loc::ConcreteInt& R) const { assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub || (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE)); const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue()); if (X) return loc::ConcreteInt(*X); else return UndefinedVal(); }
void RangeSet::IntersectInRange(BasicValueFactory &BV, Factory &F, const llvm::APSInt &Lower, const llvm::APSInt &Upper, PrimRangeSet &newRanges, PrimRangeSet::iterator &i, PrimRangeSet::iterator &e) const { // There are six cases for each range R in the set: // 1. R is entirely before the intersection range. // 2. R is entirely after the intersection range. // 3. R contains the entire intersection range. // 4. R starts before the intersection range and ends in the middle. // 5. R starts in the middle of the intersection range and ends after it. // 6. R is entirely contained in the intersection range. // These correspond to each of the conditions below. for (/* i = begin(), e = end() */; i != e; ++i) { if (i->To() < Lower) { continue; } if (i->From() > Upper) { break; } if (i->Includes(Lower)) { if (i->Includes(Upper)) { newRanges = F.add(newRanges, Range(BV.getValue(Lower), BV.getValue(Upper))); break; } else newRanges = F.add(newRanges, Range(BV.getValue(Lower), i->To())); } else { if (i->Includes(Upper)) { newRanges = F.add(newRanges, Range(i->From(), BV.getValue(Upper))); break; } else newRanges = F.add(newRanges, *i); } } }
NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) { return nonloc::ConcreteInt(BasicVals.getTruthValue(b)); }
nonloc::ConcreteInt nonloc::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const { return BasicVals.getValue(~getValue()); }
nonloc::ConcreteInt nonloc::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const { assert (U->getType() == U->getSubExpr()->getType()); assert (U->getType()->isIntegerType()); return BasicVals.getValue(-getValue()); }
NonLoc NonLoc::MakeIntVal(BasicValueFactory& BasicVals, uint64_t X, bool isUnsigned) { return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned)); }
Loc Loc::MakeNull(BasicValueFactory &BasicVals) { return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth()); }
nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V, unsigned Bits) { return LocAsInteger(Vals.getPersistentSValWithData(V, Bits)); }
NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals, BasicValueFactory& BasicVals) { return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals)); }
NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I) { return nonloc::ConcreteInt(BasicVals.getValue(I)); }
NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I, bool isUnsigned) { return nonloc::ConcreteInt(BasicVals.getValue(I, isUnsigned)); }
NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I) { return nonloc::ConcreteInt(BasicVals.getValue(APSInt(I->getValue(), I->getType()->isUnsignedIntegerType()))); }
NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T) { return nonloc::ConcreteInt(BasicVals.getValue(X, T)); }
NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X, unsigned BitWidth, bool isUnsigned) { return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned)); }