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 canReasonAbout(SVal X) const override;
234 
235   ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
236 
237   const llvm::APSInt *getSymVal(ProgramStateRef State,
238                                 SymbolRef Sym) const override;
239 
240   ProgramStateRef removeDeadBindings(ProgramStateRef State,
241                                      SymbolReaper &SymReaper) override;
242 
243   void print(ProgramStateRef State, raw_ostream &Out, const char *nl,
244              const char *sep) override;
245 
246   //===------------------------------------------------------------------===//
247   // Implementation for interface from RangedConstraintManager.
248   //===------------------------------------------------------------------===//
249 
250   ProgramStateRef assumeSymNE(ProgramStateRef State, SymbolRef Sym,
251                               const llvm::APSInt &V,
252                               const llvm::APSInt &Adjustment) override;
253 
254   ProgramStateRef assumeSymEQ(ProgramStateRef State, SymbolRef Sym,
255                               const llvm::APSInt &V,
256                               const llvm::APSInt &Adjustment) override;
257 
258   ProgramStateRef assumeSymLT(ProgramStateRef State, SymbolRef Sym,
259                               const llvm::APSInt &V,
260                               const llvm::APSInt &Adjustment) override;
261 
262   ProgramStateRef assumeSymGT(ProgramStateRef State, SymbolRef Sym,
263                               const llvm::APSInt &V,
264                               const llvm::APSInt &Adjustment) override;
265 
266   ProgramStateRef assumeSymLE(ProgramStateRef State, SymbolRef Sym,
267                               const llvm::APSInt &V,
268                               const llvm::APSInt &Adjustment) override;
269 
270   ProgramStateRef assumeSymGE(ProgramStateRef State, SymbolRef Sym,
271                               const llvm::APSInt &V,
272                               const llvm::APSInt &Adjustment) override;
273 
274   ProgramStateRef assumeSymWithinInclusiveRange(
275       ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
276       const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
277 
278   ProgramStateRef assumeSymOutsideInclusiveRange(
279       ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
280       const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
281 
282 private:
283   RangeSet::Factory F;
284 
285   RangeSet getRange(ProgramStateRef State, SymbolRef Sym);
286   const RangeSet* getRangeForMinusSymbol(ProgramStateRef State,
287                                          SymbolRef Sym);
288 
289   RangeSet getSymLTRange(ProgramStateRef St, SymbolRef Sym,
290                          const llvm::APSInt &Int,
291                          const llvm::APSInt &Adjustment);
292   RangeSet getSymGTRange(ProgramStateRef St, SymbolRef Sym,
293                          const llvm::APSInt &Int,
294                          const llvm::APSInt &Adjustment);
295   RangeSet getSymLERange(ProgramStateRef St, SymbolRef Sym,
296                          const llvm::APSInt &Int,
297                          const llvm::APSInt &Adjustment);
298   RangeSet getSymLERange(llvm::function_ref<RangeSet()> RS,
299                          const llvm::APSInt &Int,
300                          const llvm::APSInt &Adjustment);
301   RangeSet getSymGERange(ProgramStateRef St, SymbolRef Sym,
302                          const llvm::APSInt &Int,
303                          const llvm::APSInt &Adjustment);
304 
305 };
306 
307 } // end anonymous namespace
308 
309 std::unique_ptr<ConstraintManager>
310 ento::CreateRangeConstraintManager(ProgramStateManager &StMgr, SubEngine *Eng) {
311   return llvm::make_unique<RangeConstraintManager>(Eng, StMgr.getSValBuilder());
312 }
313 
314 bool RangeConstraintManager::canReasonAbout(SVal X) const {
315   Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
316   if (SymVal && SymVal->isExpression()) {
317     const SymExpr *SE = SymVal->getSymbol();
318 
319     if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
320       switch (SIE->getOpcode()) {
321       // We don't reason yet about bitwise-constraints on symbolic values.
322       case BO_And:
323       case BO_Or:
324       case BO_Xor:
325         return false;
326       // We don't reason yet about these arithmetic constraints on
327       // symbolic values.
328       case BO_Mul:
329       case BO_Div:
330       case BO_Rem:
331       case BO_Shl:
332       case BO_Shr:
333         return false;
334       // All other cases.
335       default:
336         return true;
337       }
338     }
339 
340     if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
341       // FIXME: Handle <=> here.
342       if (BinaryOperator::isEqualityOp(SSE->getOpcode()) ||
343           BinaryOperator::isRelationalOp(SSE->getOpcode())) {
344         // We handle Loc <> Loc comparisons, but not (yet) NonLoc <> NonLoc.
345         // We've recently started producing Loc <> NonLoc comparisons (that
346         // result from casts of one of the operands between eg. intptr_t and
347         // void *), but we can't reason about them yet.
348         if (Loc::isLocType(SSE->getLHS()->getType())) {
349           return Loc::isLocType(SSE->getRHS()->getType());
350         }
351       }
352     }
353 
354     return false;
355   }
356 
357   return true;
358 }
359 
360 ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
361                                                     SymbolRef Sym) {
362   const RangeSet *Ranges = State->get<ConstraintRange>(Sym);
363 
364   // If we don't have any information about this symbol, it's underconstrained.
365   if (!Ranges)
366     return ConditionTruthVal();
367 
368   // If we have a concrete value, see if it's zero.
369   if (const llvm::APSInt *Value = Ranges->getConcreteValue())
370     return *Value == 0;
371 
372   BasicValueFactory &BV = getBasicVals();
373   APSIntType IntType = BV.getAPSIntType(Sym->getType());
374   llvm::APSInt Zero = IntType.getZeroValue();
375 
376   // Check if zero is in the set of possible values.
377   if (Ranges->Intersect(BV, F, Zero, Zero).isEmpty())
378     return false;
379 
380   // Zero is a possible value, but it is not the /only/ possible value.
381   return ConditionTruthVal();
382 }
383 
384 const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
385                                                       SymbolRef Sym) const {
386   const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(Sym);
387   return T ? T->getConcreteValue() : nullptr;
388 }
389 
390 /// Scan all symbols referenced by the constraints. If the symbol is not alive
391 /// as marked in LSymbols, mark it as dead in DSymbols.
392 ProgramStateRef
393 RangeConstraintManager::removeDeadBindings(ProgramStateRef State,
394                                            SymbolReaper &SymReaper) {
395   bool Changed = false;
396   ConstraintRangeTy CR = State->get<ConstraintRange>();
397   ConstraintRangeTy::Factory &CRFactory = State->get_context<ConstraintRange>();
398 
399   for (ConstraintRangeTy::iterator I = CR.begin(), E = CR.end(); I != E; ++I) {
400     SymbolRef Sym = I.getKey();
401     if (SymReaper.isDead(Sym)) {
402       Changed = true;
403       CR = CRFactory.remove(CR, Sym);
404     }
405   }
406 
407   return Changed ? State->set<ConstraintRange>(CR) : State;
408 }
409 
410 /// Return a range set subtracting zero from \p Domain.
411 static RangeSet assumeNonZero(
412     BasicValueFactory &BV,
413     RangeSet::Factory &F,
414     SymbolRef Sym,
415     RangeSet Domain) {
416   APSIntType IntType = BV.getAPSIntType(Sym->getType());
417   return Domain.Intersect(BV, F, ++IntType.getZeroValue(),
418       --IntType.getZeroValue());
419 }
420 
421 /// Apply implicit constraints for bitwise OR- and AND-.
422 /// For unsigned types, bitwise OR with a constant always returns
423 /// a value greater-or-equal than the constant, and bitwise AND
424 /// returns a value less-or-equal then the constant.
425 ///
426 /// Pattern matches the expression \p Sym against those rule,
427 /// and applies the required constraints.
428 /// \p Input Previously established expression range set
429 static RangeSet applyBitwiseConstraints(
430     BasicValueFactory &BV,
431     RangeSet::Factory &F,
432     RangeSet Input,
433     const SymIntExpr* SIE) {
434   QualType T = SIE->getType();
435   bool IsUnsigned = T->isUnsignedIntegerType();
436   const llvm::APSInt &RHS = SIE->getRHS();
437   const llvm::APSInt &Zero = BV.getAPSIntType(T).getZeroValue();
438   BinaryOperator::Opcode Operator = SIE->getOpcode();
439 
440   // For unsigned types, the output of bitwise-or is bigger-or-equal than RHS.
441   if (Operator == BO_Or && IsUnsigned)
442     return Input.Intersect(BV, F, RHS, BV.getMaxValue(T));
443 
444   // Bitwise-or with a non-zero constant is always non-zero.
445   if (Operator == BO_Or && RHS != Zero)
446     return assumeNonZero(BV, F, SIE, Input);
447 
448   // For unsigned types, or positive RHS,
449   // bitwise-and output is always smaller-or-equal than RHS (assuming two's
450   // complement representation of signed types).
451   if (Operator == BO_And && (IsUnsigned || RHS >= Zero))
452     return Input.Intersect(BV, F, BV.getMinValue(T), RHS);
453 
454   return Input;
455 }
456 
457 RangeSet RangeConstraintManager::getRange(ProgramStateRef State,
458                                           SymbolRef Sym) {
459   if (ConstraintRangeTy::data_type *V = State->get<ConstraintRange>(Sym))
460     return *V;
461 
462   BasicValueFactory &BV = getBasicVals();
463 
464   // If Sym is a difference of symbols A - B, then maybe we have range set
465   // stored for B - A.
466   if (const RangeSet *R = getRangeForMinusSymbol(State, Sym))
467     return R->Negate(BV, F);
468 
469   // Lazily generate a new RangeSet representing all possible values for the
470   // given symbol type.
471   QualType T = Sym->getType();
472 
473   RangeSet Result(F, BV.getMinValue(T), BV.getMaxValue(T));
474 
475   // References are known to be non-zero.
476   if (T->isReferenceType())
477     return assumeNonZero(BV, F, Sym, Result);
478 
479   // Known constraints on ranges of bitwise expressions.
480   if (const SymIntExpr* SIE = dyn_cast<SymIntExpr>(Sym))
481     return applyBitwiseConstraints(BV, F, Result, SIE);
482 
483   return Result;
484 }
485 
486 // FIXME: Once SValBuilder supports unary minus, we should use SValBuilder to
487 //        obtain the negated symbolic expression instead of constructing the
488 //        symbol manually. This will allow us to support finding ranges of not
489 //        only negated SymSymExpr-type expressions, but also of other, simpler
490 //        expressions which we currently do not know how to negate.
491 const RangeSet*
492 RangeConstraintManager::getRangeForMinusSymbol(ProgramStateRef State,
493                                                SymbolRef Sym) {
494   if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) {
495     if (SSE->getOpcode() == BO_Sub) {
496       QualType T = Sym->getType();
497       SymbolManager &SymMgr = State->getSymbolManager();
498       SymbolRef negSym = SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub,
499                                               SSE->getLHS(), T);
500       if (const RangeSet *negV = State->get<ConstraintRange>(negSym)) {
501         // Unsigned range set cannot be negated, unless it is [0, 0].
502         if ((negV->getConcreteValue() &&
503              (*negV->getConcreteValue() == 0)) ||
504             T->isSignedIntegerOrEnumerationType())
505           return negV;
506       }
507     }
508   }
509   return nullptr;
510 }
511 
512 //===------------------------------------------------------------------------===
513 // assumeSymX methods: protected interface for RangeConstraintManager.
514 //===------------------------------------------------------------------------===/
515 
516 // The syntax for ranges below is mathematical, using [x, y] for closed ranges
517 // and (x, y) for open ranges. These ranges are modular, corresponding with
518 // a common treatment of C integer overflow. This means that these methods
519 // do not have to worry about overflow; RangeSet::Intersect can handle such a
520 // "wraparound" range.
521 // As an example, the range [UINT_MAX-1, 3) contains five values: UINT_MAX-1,
522 // UINT_MAX, 0, 1, and 2.
523 
524 ProgramStateRef
525 RangeConstraintManager::assumeSymNE(ProgramStateRef St, SymbolRef Sym,
526                                     const llvm::APSInt &Int,
527                                     const llvm::APSInt &Adjustment) {
528   // Before we do any real work, see if the value can even show up.
529   APSIntType AdjustmentType(Adjustment);
530   if (AdjustmentType.testInRange(Int, true) != APSIntType::RTR_Within)
531     return St;
532 
533   llvm::APSInt Lower = AdjustmentType.convert(Int) - Adjustment;
534   llvm::APSInt Upper = Lower;
535   --Lower;
536   ++Upper;
537 
538   // [Int-Adjustment+1, Int-Adjustment-1]
539   // Notice that the lower bound is greater than the upper bound.
540   RangeSet New = getRange(St, Sym).Intersect(getBasicVals(), F, Upper, Lower);
541   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
542 }
543 
544 ProgramStateRef
545 RangeConstraintManager::assumeSymEQ(ProgramStateRef St, SymbolRef Sym,
546                                     const llvm::APSInt &Int,
547                                     const llvm::APSInt &Adjustment) {
548   // Before we do any real work, see if the value can even show up.
549   APSIntType AdjustmentType(Adjustment);
550   if (AdjustmentType.testInRange(Int, true) != APSIntType::RTR_Within)
551     return nullptr;
552 
553   // [Int-Adjustment, Int-Adjustment]
554   llvm::APSInt AdjInt = AdjustmentType.convert(Int) - Adjustment;
555   RangeSet New = getRange(St, Sym).Intersect(getBasicVals(), F, AdjInt, AdjInt);
556   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
557 }
558 
559 RangeSet RangeConstraintManager::getSymLTRange(ProgramStateRef St,
560                                                SymbolRef Sym,
561                                                const llvm::APSInt &Int,
562                                                const llvm::APSInt &Adjustment) {
563   // Before we do any real work, see if the value can even show up.
564   APSIntType AdjustmentType(Adjustment);
565   switch (AdjustmentType.testInRange(Int, true)) {
566   case APSIntType::RTR_Below:
567     return F.getEmptySet();
568   case APSIntType::RTR_Within:
569     break;
570   case APSIntType::RTR_Above:
571     return getRange(St, Sym);
572   }
573 
574   // Special case for Int == Min. This is always false.
575   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
576   llvm::APSInt Min = AdjustmentType.getMinValue();
577   if (ComparisonVal == Min)
578     return F.getEmptySet();
579 
580   llvm::APSInt Lower = Min - Adjustment;
581   llvm::APSInt Upper = ComparisonVal - Adjustment;
582   --Upper;
583 
584   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
585 }
586 
587 ProgramStateRef
588 RangeConstraintManager::assumeSymLT(ProgramStateRef St, SymbolRef Sym,
589                                     const llvm::APSInt &Int,
590                                     const llvm::APSInt &Adjustment) {
591   RangeSet New = getSymLTRange(St, Sym, Int, Adjustment);
592   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
593 }
594 
595 RangeSet RangeConstraintManager::getSymGTRange(ProgramStateRef St,
596                                                SymbolRef Sym,
597                                                const llvm::APSInt &Int,
598                                                const llvm::APSInt &Adjustment) {
599   // Before we do any real work, see if the value can even show up.
600   APSIntType AdjustmentType(Adjustment);
601   switch (AdjustmentType.testInRange(Int, true)) {
602   case APSIntType::RTR_Below:
603     return getRange(St, Sym);
604   case APSIntType::RTR_Within:
605     break;
606   case APSIntType::RTR_Above:
607     return F.getEmptySet();
608   }
609 
610   // Special case for Int == Max. This is always false.
611   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
612   llvm::APSInt Max = AdjustmentType.getMaxValue();
613   if (ComparisonVal == Max)
614     return F.getEmptySet();
615 
616   llvm::APSInt Lower = ComparisonVal - Adjustment;
617   llvm::APSInt Upper = Max - Adjustment;
618   ++Lower;
619 
620   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
621 }
622 
623 ProgramStateRef
624 RangeConstraintManager::assumeSymGT(ProgramStateRef St, SymbolRef Sym,
625                                     const llvm::APSInt &Int,
626                                     const llvm::APSInt &Adjustment) {
627   RangeSet New = getSymGTRange(St, Sym, Int, Adjustment);
628   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
629 }
630 
631 RangeSet RangeConstraintManager::getSymGERange(ProgramStateRef St,
632                                                SymbolRef Sym,
633                                                const llvm::APSInt &Int,
634                                                const llvm::APSInt &Adjustment) {
635   // Before we do any real work, see if the value can even show up.
636   APSIntType AdjustmentType(Adjustment);
637   switch (AdjustmentType.testInRange(Int, true)) {
638   case APSIntType::RTR_Below:
639     return getRange(St, Sym);
640   case APSIntType::RTR_Within:
641     break;
642   case APSIntType::RTR_Above:
643     return F.getEmptySet();
644   }
645 
646   // Special case for Int == Min. This is always feasible.
647   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
648   llvm::APSInt Min = AdjustmentType.getMinValue();
649   if (ComparisonVal == Min)
650     return getRange(St, Sym);
651 
652   llvm::APSInt Max = AdjustmentType.getMaxValue();
653   llvm::APSInt Lower = ComparisonVal - Adjustment;
654   llvm::APSInt Upper = Max - Adjustment;
655 
656   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
657 }
658 
659 ProgramStateRef
660 RangeConstraintManager::assumeSymGE(ProgramStateRef St, SymbolRef Sym,
661                                     const llvm::APSInt &Int,
662                                     const llvm::APSInt &Adjustment) {
663   RangeSet New = getSymGERange(St, Sym, Int, Adjustment);
664   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
665 }
666 
667 RangeSet RangeConstraintManager::getSymLERange(
668       llvm::function_ref<RangeSet()> RS,
669       const llvm::APSInt &Int,
670       const llvm::APSInt &Adjustment) {
671   // Before we do any real work, see if the value can even show up.
672   APSIntType AdjustmentType(Adjustment);
673   switch (AdjustmentType.testInRange(Int, true)) {
674   case APSIntType::RTR_Below:
675     return F.getEmptySet();
676   case APSIntType::RTR_Within:
677     break;
678   case APSIntType::RTR_Above:
679     return RS();
680   }
681 
682   // Special case for Int == Max. This is always feasible.
683   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
684   llvm::APSInt Max = AdjustmentType.getMaxValue();
685   if (ComparisonVal == Max)
686     return RS();
687 
688   llvm::APSInt Min = AdjustmentType.getMinValue();
689   llvm::APSInt Lower = Min - Adjustment;
690   llvm::APSInt Upper = ComparisonVal - Adjustment;
691 
692   return RS().Intersect(getBasicVals(), F, Lower, Upper);
693 }
694 
695 RangeSet RangeConstraintManager::getSymLERange(ProgramStateRef St,
696                                                SymbolRef Sym,
697                                                const llvm::APSInt &Int,
698                                                const llvm::APSInt &Adjustment) {
699   return getSymLERange([&] { return getRange(St, Sym); }, Int, Adjustment);
700 }
701 
702 ProgramStateRef
703 RangeConstraintManager::assumeSymLE(ProgramStateRef St, SymbolRef Sym,
704                                     const llvm::APSInt &Int,
705                                     const llvm::APSInt &Adjustment) {
706   RangeSet New = getSymLERange(St, Sym, Int, Adjustment);
707   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
708 }
709 
710 ProgramStateRef RangeConstraintManager::assumeSymWithinInclusiveRange(
711     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
712     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
713   RangeSet New = getSymGERange(State, Sym, From, Adjustment);
714   if (New.isEmpty())
715     return nullptr;
716   RangeSet Out = getSymLERange([&] { return New; }, To, Adjustment);
717   return Out.isEmpty() ? nullptr : State->set<ConstraintRange>(Sym, Out);
718 }
719 
720 ProgramStateRef RangeConstraintManager::assumeSymOutsideInclusiveRange(
721     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
722     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
723   RangeSet RangeLT = getSymLTRange(State, Sym, From, Adjustment);
724   RangeSet RangeGT = getSymGTRange(State, Sym, To, Adjustment);
725   RangeSet New(RangeLT.addRange(F, RangeGT));
726   return New.isEmpty() ? nullptr : State->set<ConstraintRange>(Sym, New);
727 }
728 
729 //===------------------------------------------------------------------------===
730 // Pretty-printing.
731 //===------------------------------------------------------------------------===/
732 
733 void RangeConstraintManager::print(ProgramStateRef St, raw_ostream &Out,
734                                    const char *nl, const char *sep) {
735 
736   ConstraintRangeTy Ranges = St->get<ConstraintRange>();
737 
738   if (Ranges.isEmpty()) {
739     Out << nl << sep << "Ranges are empty." << nl;
740     return;
741   }
742 
743   Out << nl << sep << "Ranges of symbol values:";
744   for (ConstraintRangeTy::iterator I = Ranges.begin(), E = Ranges.end(); I != E;
745        ++I) {
746     Out << nl << ' ' << I.getKey() << " : ";
747     I.getData().print(Out);
748   }
749   Out << nl;
750 }
751