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