1 //== RangeConstraintManager.cpp - Manage range constraints.------*- C++ -*--==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines RangeConstraintManager, a class that tracks simple
11 //  equality and inequality constraints on symbolic values of ProgramState.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
16 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
17 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
18 #include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
19 #include "llvm/ADT/FoldingSet.h"
20 #include "llvm/ADT/ImmutableSet.h"
21 #include "llvm/Support/raw_ostream.h"
22 
23 using namespace clang;
24 using namespace ento;
25 
26 void RangeSet::IntersectInRange(BasicValueFactory &BV, Factory &F,
27                       const llvm::APSInt &Lower, const llvm::APSInt &Upper,
28                       PrimRangeSet &newRanges, PrimRangeSet::iterator &i,
29                       PrimRangeSet::iterator &e) const {
30   // There are six cases for each range R in the set:
31   //   1. R is entirely before the intersection range.
32   //   2. R is entirely after the intersection range.
33   //   3. R contains the entire intersection range.
34   //   4. R starts before the intersection range and ends in the middle.
35   //   5. R starts in the middle of the intersection range and ends after it.
36   //   6. R is entirely contained in the intersection range.
37   // These correspond to each of the conditions below.
38   for (/* i = begin(), e = end() */; i != e; ++i) {
39     if (i->To() < Lower) {
40       continue;
41     }
42     if (i->From() > Upper) {
43       break;
44     }
45 
46     if (i->Includes(Lower)) {
47       if (i->Includes(Upper)) {
48         newRanges =
49             F.add(newRanges, Range(BV.getValue(Lower), BV.getValue(Upper)));
50         break;
51       } else
52         newRanges = F.add(newRanges, Range(BV.getValue(Lower), i->To()));
53     } else {
54       if (i->Includes(Upper)) {
55         newRanges = F.add(newRanges, Range(i->From(), BV.getValue(Upper)));
56         break;
57       } else
58         newRanges = F.add(newRanges, *i);
59     }
60   }
61 }
62 
63 const llvm::APSInt &RangeSet::getMinValue() const {
64   assert(!isEmpty());
65   return ranges.begin()->From();
66 }
67 
68 bool RangeSet::pin(llvm::APSInt &Lower, llvm::APSInt &Upper) const {
69   // This function has nine cases, the cartesian product of range-testing
70   // both the upper and lower bounds against the symbol's type.
71   // Each case requires a different pinning operation.
72   // The function returns false if the described range is entirely outside
73   // the range of values for the associated symbol.
74   APSIntType Type(getMinValue());
75   APSIntType::RangeTestResultKind LowerTest = Type.testInRange(Lower, true);
76   APSIntType::RangeTestResultKind UpperTest = Type.testInRange(Upper, true);
77 
78   switch (LowerTest) {
79   case APSIntType::RTR_Below:
80     switch (UpperTest) {
81     case APSIntType::RTR_Below:
82       // The entire range is outside the symbol's set of possible values.
83       // If this is a conventionally-ordered range, the state is infeasible.
84       if (Lower <= Upper)
85         return false;
86 
87       // However, if the range wraps around, it spans all possible values.
88       Lower = Type.getMinValue();
89       Upper = Type.getMaxValue();
90       break;
91     case APSIntType::RTR_Within:
92       // The range starts below what's possible but ends within it. Pin.
93       Lower = Type.getMinValue();
94       Type.apply(Upper);
95       break;
96     case APSIntType::RTR_Above:
97       // The range spans all possible values for the symbol. Pin.
98       Lower = Type.getMinValue();
99       Upper = Type.getMaxValue();
100       break;
101     }
102     break;
103   case APSIntType::RTR_Within:
104     switch (UpperTest) {
105     case APSIntType::RTR_Below:
106       // The range wraps around, but all lower values are not possible.
107       Type.apply(Lower);
108       Upper = Type.getMaxValue();
109       break;
110     case APSIntType::RTR_Within:
111       // The range may or may not wrap around, but both limits are valid.
112       Type.apply(Lower);
113       Type.apply(Upper);
114       break;
115     case APSIntType::RTR_Above:
116       // The range starts within what's possible but ends above it. Pin.
117       Type.apply(Lower);
118       Upper = Type.getMaxValue();
119       break;
120     }
121     break;
122   case APSIntType::RTR_Above:
123     switch (UpperTest) {
124     case APSIntType::RTR_Below:
125       // The range wraps but is outside the symbol's set of possible values.
126       return false;
127     case APSIntType::RTR_Within:
128       // The range starts above what's possible but ends within it (wrap).
129       Lower = Type.getMinValue();
130       Type.apply(Upper);
131       break;
132     case APSIntType::RTR_Above:
133       // The entire range is outside the symbol's set of possible values.
134       // If this is a conventionally-ordered range, the state is infeasible.
135       if (Lower <= Upper)
136         return false;
137 
138       // However, if the range wraps around, it spans all possible values.
139       Lower = Type.getMinValue();
140       Upper = Type.getMaxValue();
141       break;
142     }
143     break;
144   }
145 
146   return true;
147 }
148 
149 // Returns a set containing the values in the receiving set, intersected with
150 // the closed range [Lower, Upper]. Unlike the Range type, this range uses
151 // modular arithmetic, corresponding to the common treatment of C integer
152 // overflow. Thus, if the Lower bound is greater than the Upper bound, the
153 // range is taken to wrap around. This is equivalent to taking the
154 // intersection with the two ranges [Min, Upper] and [Lower, Max],
155 // or, alternatively, /removing/ all integers between Upper and Lower.
156 RangeSet RangeSet::Intersect(BasicValueFactory &BV, Factory &F,
157                              llvm::APSInt Lower, llvm::APSInt Upper) const {
158   if (!pin(Lower, Upper))
159     return F.getEmptySet();
160 
161   PrimRangeSet newRanges = F.getEmptySet();
162 
163   PrimRangeSet::iterator i = begin(), e = end();
164   if (Lower <= Upper)
165     IntersectInRange(BV, F, Lower, Upper, newRanges, i, e);
166   else {
167     // The order of the next two statements is important!
168     // IntersectInRange() does not reset the iteration state for i and e.
169     // Therefore, the lower range most be handled first.
170     IntersectInRange(BV, F, BV.getMinValue(Upper), Upper, newRanges, i, e);
171     IntersectInRange(BV, F, Lower, BV.getMaxValue(Lower), newRanges, i, e);
172   }
173 
174   return newRanges;
175 }
176 
177 // Turn all [A, B] ranges to [-B, -A]. Ranges [MIN, B] are turned to range set
178 // [MIN, MIN] U [-B, MAX], when MIN and MAX are the minimal and the maximal
179 // signed values of the type.
180 RangeSet RangeSet::Negate(BasicValueFactory &BV, Factory &F) const {
181   PrimRangeSet newRanges = F.getEmptySet();
182 
183   for (iterator i = begin(), e = end(); i != e; ++i) {
184     const llvm::APSInt &from = i->From(), &to = i->To();
185     const llvm::APSInt &newTo = (from.isMinSignedValue() ?
186                                  BV.getMaxValue(from) :
187                                  BV.getValue(- from));
188     if (to.isMaxSignedValue() && !newRanges.isEmpty() &&
189         newRanges.begin()->From().isMinSignedValue()) {
190       assert(newRanges.begin()->To().isMinSignedValue() &&
191              "Ranges should not overlap");
192       assert(!from.isMinSignedValue() && "Ranges should not overlap");
193       const llvm::APSInt &newFrom = newRanges.begin()->From();
194       newRanges =
195         F.add(F.remove(newRanges, *newRanges.begin()), Range(newFrom, newTo));
196     } else if (!to.isMinSignedValue()) {
197       const llvm::APSInt &newFrom = BV.getValue(- to);
198       newRanges = F.add(newRanges, Range(newFrom, newTo));
199     }
200     if (from.isMinSignedValue()) {
201       newRanges = F.add(newRanges, Range(BV.getMinValue(from),
202                                          BV.getMinValue(from)));
203     }
204   }
205 
206   return newRanges;
207 }
208 
209 void RangeSet::print(raw_ostream &os) const {
210   bool isFirst = true;
211   os << "{ ";
212   for (iterator i = begin(), e = end(); i != e; ++i) {
213     if (isFirst)
214       isFirst = false;
215     else
216       os << ", ";
217 
218     os << '[' << i->From().toString(10) << ", " << i->To().toString(10)
219        << ']';
220   }
221   os << " }";
222 }
223 
224 namespace {
225 class RangeConstraintManager : public RangedConstraintManager {
226 public:
227   RangeConstraintManager(SubEngine *SE, SValBuilder &SVB)
228       : RangedConstraintManager(SE, SVB) {}
229 
230   //===------------------------------------------------------------------===//
231   // Implementation for interface from ConstraintManager.
232   //===------------------------------------------------------------------===//
233 
234   bool canReasonAbout(SVal X) const override;
235 
236   ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
237 
238   const llvm::APSInt *getSymVal(ProgramStateRef State,
239                                 SymbolRef Sym) const override;
240 
241   ProgramStateRef removeDeadBindings(ProgramStateRef State,
242                                      SymbolReaper &SymReaper) override;
243 
244   void print(ProgramStateRef State, raw_ostream &Out, const char *nl,
245              const char *sep) override;
246 
247   //===------------------------------------------------------------------===//
248   // Implementation for interface from RangedConstraintManager.
249   //===------------------------------------------------------------------===//
250 
251   ProgramStateRef assumeSymNE(ProgramStateRef State, SymbolRef Sym,
252                               const llvm::APSInt &V,
253                               const llvm::APSInt &Adjustment) override;
254 
255   ProgramStateRef assumeSymEQ(ProgramStateRef State, SymbolRef Sym,
256                               const llvm::APSInt &V,
257                               const llvm::APSInt &Adjustment) override;
258 
259   ProgramStateRef assumeSymLT(ProgramStateRef State, SymbolRef Sym,
260                               const llvm::APSInt &V,
261                               const llvm::APSInt &Adjustment) override;
262 
263   ProgramStateRef assumeSymGT(ProgramStateRef State, SymbolRef Sym,
264                               const llvm::APSInt &V,
265                               const llvm::APSInt &Adjustment) override;
266 
267   ProgramStateRef assumeSymLE(ProgramStateRef State, SymbolRef Sym,
268                               const llvm::APSInt &V,
269                               const llvm::APSInt &Adjustment) override;
270 
271   ProgramStateRef assumeSymGE(ProgramStateRef State, SymbolRef Sym,
272                               const llvm::APSInt &V,
273                               const llvm::APSInt &Adjustment) override;
274 
275   ProgramStateRef assumeSymWithinInclusiveRange(
276       ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
277       const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
278 
279   ProgramStateRef assumeSymOutsideInclusiveRange(
280       ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
281       const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
282 
283 private:
284   RangeSet::Factory F;
285 
286   RangeSet getRange(ProgramStateRef State, SymbolRef Sym);
287   const RangeSet* getRangeForMinusSymbol(ProgramStateRef State,
288                                          SymbolRef Sym);
289 
290   RangeSet getSymLTRange(ProgramStateRef St, SymbolRef Sym,
291                          const llvm::APSInt &Int,
292                          const llvm::APSInt &Adjustment);
293   RangeSet getSymGTRange(ProgramStateRef St, SymbolRef Sym,
294                          const llvm::APSInt &Int,
295                          const llvm::APSInt &Adjustment);
296   RangeSet getSymLERange(ProgramStateRef St, SymbolRef Sym,
297                          const llvm::APSInt &Int,
298                          const llvm::APSInt &Adjustment);
299   RangeSet getSymLERange(llvm::function_ref<RangeSet()> RS,
300                          const llvm::APSInt &Int,
301                          const llvm::APSInt &Adjustment);
302   RangeSet getSymGERange(ProgramStateRef St, SymbolRef Sym,
303                          const llvm::APSInt &Int,
304                          const llvm::APSInt &Adjustment);
305 
306 };
307 
308 } // end anonymous namespace
309 
310 std::unique_ptr<ConstraintManager>
311 ento::CreateRangeConstraintManager(ProgramStateManager &StMgr, SubEngine *Eng) {
312   return llvm::make_unique<RangeConstraintManager>(Eng, StMgr.getSValBuilder());
313 }
314 
315 bool RangeConstraintManager::canReasonAbout(SVal X) const {
316   Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
317   if (SymVal && SymVal->isExpression()) {
318     const SymExpr *SE = SymVal->getSymbol();
319 
320     if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
321       switch (SIE->getOpcode()) {
322       // We don't reason yet about bitwise-constraints on symbolic values.
323       case BO_And:
324       case BO_Or:
325       case BO_Xor:
326         return false;
327       // We don't reason yet about these arithmetic constraints on
328       // symbolic values.
329       case BO_Mul:
330       case BO_Div:
331       case BO_Rem:
332       case BO_Shl:
333       case BO_Shr:
334         return false;
335       // All other cases.
336       default:
337         return true;
338       }
339     }
340 
341     if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
342       // FIXME: Handle <=> here.
343       if (BinaryOperator::isEqualityOp(SSE->getOpcode()) ||
344           BinaryOperator::isRelationalOp(SSE->getOpcode())) {
345         // We handle Loc <> Loc comparisons, but not (yet) NonLoc <> NonLoc.
346         if (Loc::isLocType(SSE->getLHS()->getType())) {
347           assert(Loc::isLocType(SSE->getRHS()->getType()));
348           return true;
349         }
350       }
351     }
352 
353     return false;
354   }
355 
356   return true;
357 }
358 
359 ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
360                                                     SymbolRef Sym) {
361   const RangeSet *Ranges = State->get<ConstraintRange>(Sym);
362 
363   // If we don't have any information about this symbol, it's underconstrained.
364   if (!Ranges)
365     return ConditionTruthVal();
366 
367   // If we have a concrete value, see if it's zero.
368   if (const llvm::APSInt *Value = Ranges->getConcreteValue())
369     return *Value == 0;
370 
371   BasicValueFactory &BV = getBasicVals();
372   APSIntType IntType = BV.getAPSIntType(Sym->getType());
373   llvm::APSInt Zero = IntType.getZeroValue();
374 
375   // Check if zero is in the set of possible values.
376   if (Ranges->Intersect(BV, F, Zero, Zero).isEmpty())
377     return false;
378 
379   // Zero is a possible value, but it is not the /only/ possible value.
380   return ConditionTruthVal();
381 }
382 
383 const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
384                                                       SymbolRef Sym) const {
385   const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(Sym);
386   return T ? T->getConcreteValue() : nullptr;
387 }
388 
389 /// Scan all symbols referenced by the constraints. If the symbol is not alive
390 /// as marked in LSymbols, mark it as dead in DSymbols.
391 ProgramStateRef
392 RangeConstraintManager::removeDeadBindings(ProgramStateRef State,
393                                            SymbolReaper &SymReaper) {
394   bool Changed = false;
395   ConstraintRangeTy CR = State->get<ConstraintRange>();
396   ConstraintRangeTy::Factory &CRFactory = State->get_context<ConstraintRange>();
397 
398   for (ConstraintRangeTy::iterator I = CR.begin(), E = CR.end(); I != E; ++I) {
399     SymbolRef Sym = I.getKey();
400     if (SymReaper.maybeDead(Sym)) {
401       Changed = true;
402       CR = CRFactory.remove(CR, Sym);
403     }
404   }
405 
406   return Changed ? State->set<ConstraintRange>(CR) : State;
407 }
408 
409 /// Return a range set subtracting zero from \p Domain.
410 static RangeSet assumeNonZero(
411     BasicValueFactory &BV,
412     RangeSet::Factory &F,
413     SymbolRef Sym,
414     RangeSet Domain) {
415   APSIntType IntType = BV.getAPSIntType(Sym->getType());
416   return Domain.Intersect(BV, F, ++IntType.getZeroValue(),
417       --IntType.getZeroValue());
418 }
419 
420 /// Apply implicit constraints for bitwise OR- and AND-.
421 /// For unsigned types, bitwise OR with a constant always returns
422 /// a value greater-or-equal than the constant, and bitwise AND
423 /// returns a value less-or-equal then the constant.
424 ///
425 /// Pattern matches the expression \p Sym against those rule,
426 /// and applies the required constraints.
427 /// \p Input Previously established expression range set
428 static RangeSet applyBitwiseConstraints(
429     BasicValueFactory &BV,
430     RangeSet::Factory &F,
431     RangeSet Input,
432     const SymIntExpr* SIE) {
433   QualType T = SIE->getType();
434   bool IsUnsigned = T->isUnsignedIntegerType();
435   const llvm::APSInt &RHS = SIE->getRHS();
436   const llvm::APSInt &Zero = BV.getAPSIntType(T).getZeroValue();
437   BinaryOperator::Opcode Operator = SIE->getOpcode();
438 
439   // For unsigned types, the output of bitwise-or is bigger-or-equal than RHS.
440   if (Operator == BO_Or && IsUnsigned)
441     return Input.Intersect(BV, F, RHS, BV.getMaxValue(T));
442 
443   // Bitwise-or with a non-zero constant is always non-zero.
444   if (Operator == BO_Or && RHS != Zero)
445     return assumeNonZero(BV, F, SIE, Input);
446 
447   // For unsigned types, or positive RHS,
448   // bitwise-and output is always smaller-or-equal than RHS (assuming two's
449   // complement representation of signed types).
450   if (Operator == BO_And && (IsUnsigned || RHS >= Zero))
451     return Input.Intersect(BV, F, BV.getMinValue(T), RHS);
452 
453   return Input;
454 }
455 
456 RangeSet RangeConstraintManager::getRange(ProgramStateRef State,
457                                           SymbolRef Sym) {
458   if (ConstraintRangeTy::data_type *V = State->get<ConstraintRange>(Sym))
459     return *V;
460 
461   BasicValueFactory &BV = getBasicVals();
462 
463   // If Sym is a difference of symbols A - B, then maybe we have range set
464   // stored for B - A.
465   if (const RangeSet *R = getRangeForMinusSymbol(State, Sym))
466     return R->Negate(BV, F);
467 
468   // Lazily generate a new RangeSet representing all possible values for the
469   // given symbol type.
470   QualType T = Sym->getType();
471 
472   RangeSet Result(F, BV.getMinValue(T), BV.getMaxValue(T));
473 
474   // References are known to be non-zero.
475   if (T->isReferenceType())
476     return assumeNonZero(BV, F, Sym, Result);
477 
478   // Known constraints on ranges of bitwise expressions.
479   if (const SymIntExpr* SIE = dyn_cast<SymIntExpr>(Sym))
480     return applyBitwiseConstraints(BV, F, Result, SIE);
481 
482   return Result;
483 }
484 
485 // FIXME: Once SValBuilder supports unary minus, we should use SValBuilder to
486 //        obtain the negated symbolic expression instead of constructing the
487 //        symbol manually. This will allow us to support finding ranges of not
488 //        only negated SymSymExpr-type expressions, but also of other, simpler
489 //        expressions which we currently do not know how to negate.
490 const RangeSet*
491 RangeConstraintManager::getRangeForMinusSymbol(ProgramStateRef State,
492                                                SymbolRef Sym) {
493   if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) {
494     if (SSE->getOpcode() == BO_Sub) {
495       QualType T = Sym->getType();
496       SymbolManager &SymMgr = State->getSymbolManager();
497       SymbolRef negSym = SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub,
498                                               SSE->getLHS(), T);
499       if (const RangeSet *negV = State->get<ConstraintRange>(negSym)) {
500         // Unsigned range set cannot be negated, unless it is [0, 0].
501         if ((negV->getConcreteValue() &&
502              (*negV->getConcreteValue() == 0)) ||
503             T->isSignedIntegerOrEnumerationType())
504           return negV;
505       }
506     }
507   }
508   return nullptr;
509 }
510 
511 //===------------------------------------------------------------------------===
512 // assumeSymX methods: protected interface for RangeConstraintManager.
513 //===------------------------------------------------------------------------===/
514 
515 // The syntax for ranges below is mathematical, using [x, y] for closed ranges
516 // and (x, y) for open ranges. These ranges are modular, corresponding with
517 // a common treatment of C integer overflow. This means that these methods
518 // do not have to worry about overflow; RangeSet::Intersect can handle such a
519 // "wraparound" range.
520 // As an example, the range [UINT_MAX-1, 3) contains five values: UINT_MAX-1,
521 // UINT_MAX, 0, 1, and 2.
522 
523 ProgramStateRef
524 RangeConstraintManager::assumeSymNE(ProgramStateRef St, SymbolRef Sym,
525                                     const llvm::APSInt &Int,
526                                     const llvm::APSInt &Adjustment) {
527   // Before we do any real work, see if the value can even show up.
528   APSIntType AdjustmentType(Adjustment);
529   if (AdjustmentType.testInRange(Int, true) != APSIntType::RTR_Within)
530     return St;
531 
532   llvm::APSInt Lower = AdjustmentType.convert(Int) - Adjustment;
533   llvm::APSInt Upper = Lower;
534   --Lower;
535   ++Upper;
536 
537   // [Int-Adjustment+1, Int-Adjustment-1]
538   // Notice that the lower bound is greater than the upper bound.
539   RangeSet New = getRange(St, Sym).Intersect(getBasicVals(), F, Upper, Lower);
540   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
541 }
542 
543 ProgramStateRef
544 RangeConstraintManager::assumeSymEQ(ProgramStateRef St, SymbolRef Sym,
545                                     const llvm::APSInt &Int,
546                                     const llvm::APSInt &Adjustment) {
547   // Before we do any real work, see if the value can even show up.
548   APSIntType AdjustmentType(Adjustment);
549   if (AdjustmentType.testInRange(Int, true) != APSIntType::RTR_Within)
550     return nullptr;
551 
552   // [Int-Adjustment, Int-Adjustment]
553   llvm::APSInt AdjInt = AdjustmentType.convert(Int) - Adjustment;
554   RangeSet New = getRange(St, Sym).Intersect(getBasicVals(), F, AdjInt, AdjInt);
555   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
556 }
557 
558 RangeSet RangeConstraintManager::getSymLTRange(ProgramStateRef St,
559                                                SymbolRef Sym,
560                                                const llvm::APSInt &Int,
561                                                const llvm::APSInt &Adjustment) {
562   // Before we do any real work, see if the value can even show up.
563   APSIntType AdjustmentType(Adjustment);
564   switch (AdjustmentType.testInRange(Int, true)) {
565   case APSIntType::RTR_Below:
566     return F.getEmptySet();
567   case APSIntType::RTR_Within:
568     break;
569   case APSIntType::RTR_Above:
570     return getRange(St, Sym);
571   }
572 
573   // Special case for Int == Min. This is always false.
574   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
575   llvm::APSInt Min = AdjustmentType.getMinValue();
576   if (ComparisonVal == Min)
577     return F.getEmptySet();
578 
579   llvm::APSInt Lower = Min - Adjustment;
580   llvm::APSInt Upper = ComparisonVal - Adjustment;
581   --Upper;
582 
583   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
584 }
585 
586 ProgramStateRef
587 RangeConstraintManager::assumeSymLT(ProgramStateRef St, SymbolRef Sym,
588                                     const llvm::APSInt &Int,
589                                     const llvm::APSInt &Adjustment) {
590   RangeSet New = getSymLTRange(St, Sym, Int, Adjustment);
591   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
592 }
593 
594 RangeSet RangeConstraintManager::getSymGTRange(ProgramStateRef St,
595                                                SymbolRef Sym,
596                                                const llvm::APSInt &Int,
597                                                const llvm::APSInt &Adjustment) {
598   // Before we do any real work, see if the value can even show up.
599   APSIntType AdjustmentType(Adjustment);
600   switch (AdjustmentType.testInRange(Int, true)) {
601   case APSIntType::RTR_Below:
602     return getRange(St, Sym);
603   case APSIntType::RTR_Within:
604     break;
605   case APSIntType::RTR_Above:
606     return F.getEmptySet();
607   }
608 
609   // Special case for Int == Max. This is always false.
610   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
611   llvm::APSInt Max = AdjustmentType.getMaxValue();
612   if (ComparisonVal == Max)
613     return F.getEmptySet();
614 
615   llvm::APSInt Lower = ComparisonVal - Adjustment;
616   llvm::APSInt Upper = Max - Adjustment;
617   ++Lower;
618 
619   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
620 }
621 
622 ProgramStateRef
623 RangeConstraintManager::assumeSymGT(ProgramStateRef St, SymbolRef Sym,
624                                     const llvm::APSInt &Int,
625                                     const llvm::APSInt &Adjustment) {
626   RangeSet New = getSymGTRange(St, Sym, Int, Adjustment);
627   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
628 }
629 
630 RangeSet RangeConstraintManager::getSymGERange(ProgramStateRef St,
631                                                SymbolRef Sym,
632                                                const llvm::APSInt &Int,
633                                                const llvm::APSInt &Adjustment) {
634   // Before we do any real work, see if the value can even show up.
635   APSIntType AdjustmentType(Adjustment);
636   switch (AdjustmentType.testInRange(Int, true)) {
637   case APSIntType::RTR_Below:
638     return getRange(St, Sym);
639   case APSIntType::RTR_Within:
640     break;
641   case APSIntType::RTR_Above:
642     return F.getEmptySet();
643   }
644 
645   // Special case for Int == Min. This is always feasible.
646   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
647   llvm::APSInt Min = AdjustmentType.getMinValue();
648   if (ComparisonVal == Min)
649     return getRange(St, Sym);
650 
651   llvm::APSInt Max = AdjustmentType.getMaxValue();
652   llvm::APSInt Lower = ComparisonVal - Adjustment;
653   llvm::APSInt Upper = Max - Adjustment;
654 
655   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
656 }
657 
658 ProgramStateRef
659 RangeConstraintManager::assumeSymGE(ProgramStateRef St, SymbolRef Sym,
660                                     const llvm::APSInt &Int,
661                                     const llvm::APSInt &Adjustment) {
662   RangeSet New = getSymGERange(St, Sym, Int, Adjustment);
663   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
664 }
665 
666 RangeSet RangeConstraintManager::getSymLERange(
667       llvm::function_ref<RangeSet()> RS,
668       const llvm::APSInt &Int,
669       const llvm::APSInt &Adjustment) {
670   // Before we do any real work, see if the value can even show up.
671   APSIntType AdjustmentType(Adjustment);
672   switch (AdjustmentType.testInRange(Int, true)) {
673   case APSIntType::RTR_Below:
674     return F.getEmptySet();
675   case APSIntType::RTR_Within:
676     break;
677   case APSIntType::RTR_Above:
678     return RS();
679   }
680 
681   // Special case for Int == Max. This is always feasible.
682   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
683   llvm::APSInt Max = AdjustmentType.getMaxValue();
684   if (ComparisonVal == Max)
685     return RS();
686 
687   llvm::APSInt Min = AdjustmentType.getMinValue();
688   llvm::APSInt Lower = Min - Adjustment;
689   llvm::APSInt Upper = ComparisonVal - Adjustment;
690 
691   return RS().Intersect(getBasicVals(), F, Lower, Upper);
692 }
693 
694 RangeSet RangeConstraintManager::getSymLERange(ProgramStateRef St,
695                                                SymbolRef Sym,
696                                                const llvm::APSInt &Int,
697                                                const llvm::APSInt &Adjustment) {
698   return getSymLERange([&] { return getRange(St, Sym); }, Int, Adjustment);
699 }
700 
701 ProgramStateRef
702 RangeConstraintManager::assumeSymLE(ProgramStateRef St, SymbolRef Sym,
703                                     const llvm::APSInt &Int,
704                                     const llvm::APSInt &Adjustment) {
705   RangeSet New = getSymLERange(St, Sym, Int, Adjustment);
706   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
707 }
708 
709 ProgramStateRef RangeConstraintManager::assumeSymWithinInclusiveRange(
710     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
711     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
712   RangeSet New = getSymGERange(State, Sym, From, Adjustment);
713   if (New.isEmpty())
714     return nullptr;
715   RangeSet Out = getSymLERange([&] { return New; }, To, Adjustment);
716   return Out.isEmpty() ? nullptr : State->set<ConstraintRange>(Sym, Out);
717 }
718 
719 ProgramStateRef RangeConstraintManager::assumeSymOutsideInclusiveRange(
720     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
721     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
722   RangeSet RangeLT = getSymLTRange(State, Sym, From, Adjustment);
723   RangeSet RangeGT = getSymGTRange(State, Sym, To, Adjustment);
724   RangeSet New(RangeLT.addRange(F, RangeGT));
725   return New.isEmpty() ? nullptr : State->set<ConstraintRange>(Sym, New);
726 }
727 
728 //===------------------------------------------------------------------------===
729 // Pretty-printing.
730 //===------------------------------------------------------------------------===/
731 
732 void RangeConstraintManager::print(ProgramStateRef St, raw_ostream &Out,
733                                    const char *nl, const char *sep) {
734 
735   ConstraintRangeTy Ranges = St->get<ConstraintRange>();
736 
737   if (Ranges.isEmpty()) {
738     Out << nl << sep << "Ranges are empty." << nl;
739     return;
740   }
741 
742   Out << nl << sep << "Ranges of symbol values:";
743   for (ConstraintRangeTy::iterator I = Ranges.begin(), E = Ranges.end(); I != E;
744        ++I) {
745     Out << nl << ' ' << I.getKey() << " : ";
746     I.getData().print(Out);
747   }
748   Out << nl;
749 }
750