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/Basic/JsonSupport.h"
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   PrimRangeSet newRanges = F.getEmptySet();
159 
160   if (isEmpty() || !pin(Lower, Upper))
161     return newRanges;
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 // Returns a set containing the values in the receiving set, intersected with
178 // the range set passed as parameter.
179 RangeSet RangeSet::Intersect(BasicValueFactory &BV, Factory &F,
180                              const RangeSet &Other) const {
181   PrimRangeSet newRanges = F.getEmptySet();
182 
183   for (iterator i = Other.begin(), e = Other.end(); i != e; ++i) {
184     RangeSet newPiece = Intersect(BV, F, i->From(), i->To());
185     for (iterator j = newPiece.begin(), ee = newPiece.end(); j != ee; ++j) {
186       newRanges = F.add(newRanges, *j);
187     }
188   }
189 
190   return newRanges;
191 }
192 
193 // Turn all [A, B] ranges to [-B, -A], when "-" is a C-like unary minus
194 // operation under the values of the type.
195 //
196 // We also handle MIN because applying unary minus to MIN does not change it.
197 // Example 1:
198 // char x = -128;        // -128 is a MIN value in a range of 'char'
199 // char y = -x;          // y: -128
200 // Example 2:
201 // unsigned char x = 0;  // 0 is a MIN value in a range of 'unsigned char'
202 // unsigned char y = -x; // y: 0
203 //
204 // And it makes us to separate the range
205 // like [MIN, N] to [MIN, MIN] U [-N,MAX].
206 // For instance, whole range is {-128..127} and subrange is [-128,-126],
207 // thus [-128,-127,-126,.....] negates to [-128,.....,126,127].
208 //
209 // Negate restores disrupted ranges on bounds,
210 // e.g. [MIN, B] => [MIN, MIN] U [-B, MAX] => [MIN, B].
211 RangeSet RangeSet::Negate(BasicValueFactory &BV, Factory &F) const {
212   PrimRangeSet newRanges = F.getEmptySet();
213 
214   if (isEmpty())
215     return newRanges;
216 
217   const llvm::APSInt sampleValue = getMinValue();
218   const llvm::APSInt &MIN = BV.getMinValue(sampleValue);
219   const llvm::APSInt &MAX = BV.getMaxValue(sampleValue);
220 
221   // Handle a special case for MIN value.
222   iterator i = begin();
223   const llvm::APSInt &from = i->From();
224   const llvm::APSInt &to = i->To();
225   if (from == MIN) {
226     // If [from, to] are [MIN, MAX], then just return the same [MIN, MAX].
227     if (to == MAX) {
228       newRanges = ranges;
229     } else {
230       // Add separate range for the lowest value.
231       newRanges = F.add(newRanges, Range(MIN, MIN));
232       // Skip adding the second range in case when [from, to] are [MIN, MIN].
233       if (to != MIN) {
234         newRanges = F.add(newRanges, Range(BV.getValue(-to), MAX));
235       }
236     }
237     // Skip the first range in the loop.
238     ++i;
239   }
240 
241   // Negate all other ranges.
242   for (iterator e = end(); i != e; ++i) {
243     // Negate int values.
244     const llvm::APSInt &newFrom = BV.getValue(-i->To());
245     const llvm::APSInt &newTo = BV.getValue(-i->From());
246     // Add a negated range.
247     newRanges = F.add(newRanges, Range(newFrom, newTo));
248   }
249 
250   if (newRanges.isSingleton())
251     return newRanges;
252 
253   // Try to find and unite next ranges:
254   // [MIN, MIN] & [MIN + 1, N] => [MIN, N].
255   iterator iter1 = newRanges.begin();
256   iterator iter2 = std::next(iter1);
257 
258   if (iter1->To() == MIN && (iter2->From() - 1) == MIN) {
259     const llvm::APSInt &to = iter2->To();
260     // remove adjacent ranges
261     newRanges = F.remove(newRanges, *iter1);
262     newRanges = F.remove(newRanges, *newRanges.begin());
263     // add united range
264     newRanges = F.add(newRanges, Range(MIN, to));
265   }
266 
267   return newRanges;
268 }
269 
270 void RangeSet::print(raw_ostream &os) const {
271   bool isFirst = true;
272   os << "{ ";
273   for (iterator i = begin(), e = end(); i != e; ++i) {
274     if (isFirst)
275       isFirst = false;
276     else
277       os << ", ";
278 
279     os << '[' << i->From().toString(10) << ", " << i->To().toString(10)
280        << ']';
281   }
282   os << " }";
283 }
284 
285 namespace {
286 class RangeConstraintManager : public RangedConstraintManager {
287 public:
288   RangeConstraintManager(ExprEngine *EE, SValBuilder &SVB)
289       : RangedConstraintManager(EE, SVB) {}
290 
291   //===------------------------------------------------------------------===//
292   // Implementation for interface from ConstraintManager.
293   //===------------------------------------------------------------------===//
294 
295   bool haveEqualConstraints(ProgramStateRef S1,
296                             ProgramStateRef S2) const override {
297     return S1->get<ConstraintRange>() == S2->get<ConstraintRange>();
298   }
299 
300   bool canReasonAbout(SVal X) const override;
301 
302   ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
303 
304   const llvm::APSInt *getSymVal(ProgramStateRef State,
305                                 SymbolRef Sym) const override;
306 
307   ProgramStateRef removeDeadBindings(ProgramStateRef State,
308                                      SymbolReaper &SymReaper) override;
309 
310   void printJson(raw_ostream &Out, ProgramStateRef State, const char *NL = "\n",
311                  unsigned int Space = 0, bool IsDot = false) const override;
312 
313   //===------------------------------------------------------------------===//
314   // Implementation for interface from RangedConstraintManager.
315   //===------------------------------------------------------------------===//
316 
317   ProgramStateRef assumeSymNE(ProgramStateRef State, SymbolRef Sym,
318                               const llvm::APSInt &V,
319                               const llvm::APSInt &Adjustment) override;
320 
321   ProgramStateRef assumeSymEQ(ProgramStateRef State, SymbolRef Sym,
322                               const llvm::APSInt &V,
323                               const llvm::APSInt &Adjustment) override;
324 
325   ProgramStateRef assumeSymLT(ProgramStateRef State, SymbolRef Sym,
326                               const llvm::APSInt &V,
327                               const llvm::APSInt &Adjustment) override;
328 
329   ProgramStateRef assumeSymGT(ProgramStateRef State, SymbolRef Sym,
330                               const llvm::APSInt &V,
331                               const llvm::APSInt &Adjustment) override;
332 
333   ProgramStateRef assumeSymLE(ProgramStateRef State, SymbolRef Sym,
334                               const llvm::APSInt &V,
335                               const llvm::APSInt &Adjustment) override;
336 
337   ProgramStateRef assumeSymGE(ProgramStateRef State, SymbolRef Sym,
338                               const llvm::APSInt &V,
339                               const llvm::APSInt &Adjustment) override;
340 
341   ProgramStateRef assumeSymWithinInclusiveRange(
342       ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
343       const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
344 
345   ProgramStateRef assumeSymOutsideInclusiveRange(
346       ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
347       const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
348 
349 private:
350   RangeSet::Factory F;
351 
352   RangeSet getRange(ProgramStateRef State, SymbolRef Sym);
353   const RangeSet* getRangeForMinusSymbol(ProgramStateRef State,
354                                          SymbolRef Sym);
355 
356   RangeSet getSymLTRange(ProgramStateRef St, SymbolRef Sym,
357                          const llvm::APSInt &Int,
358                          const llvm::APSInt &Adjustment);
359   RangeSet getSymGTRange(ProgramStateRef St, SymbolRef Sym,
360                          const llvm::APSInt &Int,
361                          const llvm::APSInt &Adjustment);
362   RangeSet getSymLERange(ProgramStateRef St, SymbolRef Sym,
363                          const llvm::APSInt &Int,
364                          const llvm::APSInt &Adjustment);
365   RangeSet getSymLERange(llvm::function_ref<RangeSet()> RS,
366                          const llvm::APSInt &Int,
367                          const llvm::APSInt &Adjustment);
368   RangeSet getSymGERange(ProgramStateRef St, SymbolRef Sym,
369                          const llvm::APSInt &Int,
370                          const llvm::APSInt &Adjustment);
371 
372 };
373 
374 } // end anonymous namespace
375 
376 std::unique_ptr<ConstraintManager>
377 ento::CreateRangeConstraintManager(ProgramStateManager &StMgr,
378                                    ExprEngine *Eng) {
379   return std::make_unique<RangeConstraintManager>(Eng, StMgr.getSValBuilder());
380 }
381 
382 bool RangeConstraintManager::canReasonAbout(SVal X) const {
383   Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
384   if (SymVal && SymVal->isExpression()) {
385     const SymExpr *SE = SymVal->getSymbol();
386 
387     if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
388       switch (SIE->getOpcode()) {
389       // We don't reason yet about bitwise-constraints on symbolic values.
390       case BO_And:
391       case BO_Or:
392       case BO_Xor:
393         return false;
394       // We don't reason yet about these arithmetic constraints on
395       // symbolic values.
396       case BO_Mul:
397       case BO_Div:
398       case BO_Rem:
399       case BO_Shl:
400       case BO_Shr:
401         return false;
402       // All other cases.
403       default:
404         return true;
405       }
406     }
407 
408     if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
409       // FIXME: Handle <=> here.
410       if (BinaryOperator::isEqualityOp(SSE->getOpcode()) ||
411           BinaryOperator::isRelationalOp(SSE->getOpcode())) {
412         // We handle Loc <> Loc comparisons, but not (yet) NonLoc <> NonLoc.
413         // We've recently started producing Loc <> NonLoc comparisons (that
414         // result from casts of one of the operands between eg. intptr_t and
415         // void *), but we can't reason about them yet.
416         if (Loc::isLocType(SSE->getLHS()->getType())) {
417           return Loc::isLocType(SSE->getRHS()->getType());
418         }
419       }
420     }
421 
422     return false;
423   }
424 
425   return true;
426 }
427 
428 ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
429                                                     SymbolRef Sym) {
430   const RangeSet *Ranges = State->get<ConstraintRange>(Sym);
431 
432   // If we don't have any information about this symbol, it's underconstrained.
433   if (!Ranges)
434     return ConditionTruthVal();
435 
436   // If we have a concrete value, see if it's zero.
437   if (const llvm::APSInt *Value = Ranges->getConcreteValue())
438     return *Value == 0;
439 
440   BasicValueFactory &BV = getBasicVals();
441   APSIntType IntType = BV.getAPSIntType(Sym->getType());
442   llvm::APSInt Zero = IntType.getZeroValue();
443 
444   // Check if zero is in the set of possible values.
445   if (Ranges->Intersect(BV, F, Zero, Zero).isEmpty())
446     return false;
447 
448   // Zero is a possible value, but it is not the /only/ possible value.
449   return ConditionTruthVal();
450 }
451 
452 const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
453                                                       SymbolRef Sym) const {
454   const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(Sym);
455   return T ? T->getConcreteValue() : nullptr;
456 }
457 
458 /// Scan all symbols referenced by the constraints. If the symbol is not alive
459 /// as marked in LSymbols, mark it as dead in DSymbols.
460 ProgramStateRef
461 RangeConstraintManager::removeDeadBindings(ProgramStateRef State,
462                                            SymbolReaper &SymReaper) {
463   bool Changed = false;
464   ConstraintRangeTy CR = State->get<ConstraintRange>();
465   ConstraintRangeTy::Factory &CRFactory = State->get_context<ConstraintRange>();
466 
467   for (ConstraintRangeTy::iterator I = CR.begin(), E = CR.end(); I != E; ++I) {
468     SymbolRef Sym = I.getKey();
469     if (SymReaper.isDead(Sym)) {
470       Changed = true;
471       CR = CRFactory.remove(CR, Sym);
472     }
473   }
474 
475   return Changed ? State->set<ConstraintRange>(CR) : State;
476 }
477 
478 /// Return a range set subtracting zero from \p Domain.
479 static RangeSet assumeNonZero(
480     BasicValueFactory &BV,
481     RangeSet::Factory &F,
482     SymbolRef Sym,
483     RangeSet Domain) {
484   APSIntType IntType = BV.getAPSIntType(Sym->getType());
485   return Domain.Intersect(BV, F, ++IntType.getZeroValue(),
486       --IntType.getZeroValue());
487 }
488 
489 /// Apply implicit constraints for bitwise OR- and AND-.
490 /// For unsigned types, bitwise OR with a constant always returns
491 /// a value greater-or-equal than the constant, and bitwise AND
492 /// returns a value less-or-equal then the constant.
493 ///
494 /// Pattern matches the expression \p Sym against those rule,
495 /// and applies the required constraints.
496 /// \p Input Previously established expression range set
497 static RangeSet applyBitwiseConstraints(
498     BasicValueFactory &BV,
499     RangeSet::Factory &F,
500     RangeSet Input,
501     const SymIntExpr* SIE) {
502   QualType T = SIE->getType();
503   bool IsUnsigned = T->isUnsignedIntegerType();
504   const llvm::APSInt &RHS = SIE->getRHS();
505   const llvm::APSInt &Zero = BV.getAPSIntType(T).getZeroValue();
506   BinaryOperator::Opcode Operator = SIE->getOpcode();
507 
508   // For unsigned types, the output of bitwise-or is bigger-or-equal than RHS.
509   if (Operator == BO_Or && IsUnsigned)
510     return Input.Intersect(BV, F, RHS, BV.getMaxValue(T));
511 
512   // Bitwise-or with a non-zero constant is always non-zero.
513   if (Operator == BO_Or && RHS != Zero)
514     return assumeNonZero(BV, F, SIE, Input);
515 
516   // For unsigned types, or positive RHS,
517   // bitwise-and output is always smaller-or-equal than RHS (assuming two's
518   // complement representation of signed types).
519   if (Operator == BO_And && (IsUnsigned || RHS >= Zero))
520     return Input.Intersect(BV, F, BV.getMinValue(T), RHS);
521 
522   return Input;
523 }
524 
525 RangeSet RangeConstraintManager::getRange(ProgramStateRef State,
526                                           SymbolRef Sym) {
527   ConstraintRangeTy::data_type *V = State->get<ConstraintRange>(Sym);
528 
529   // If Sym is a difference of symbols A - B, then maybe we have range set
530   // stored for B - A.
531   BasicValueFactory &BV = getBasicVals();
532   const RangeSet *R = getRangeForMinusSymbol(State, Sym);
533 
534   // If we have range set stored for both A - B and B - A then calculate the
535   // effective range set by intersecting the range set for A - B and the
536   // negated range set of B - A.
537   if (V && R)
538     return V->Intersect(BV, F, R->Negate(BV, F));
539   if (V)
540     return *V;
541   if (R)
542     return R->Negate(BV, F);
543 
544   // Lazily generate a new RangeSet representing all possible values for the
545   // given symbol type.
546   QualType T = Sym->getType();
547 
548   RangeSet Result(F, BV.getMinValue(T), BV.getMaxValue(T));
549 
550   // References are known to be non-zero.
551   if (T->isReferenceType())
552     return assumeNonZero(BV, F, Sym, Result);
553 
554   // Known constraints on ranges of bitwise expressions.
555   if (const SymIntExpr* SIE = dyn_cast<SymIntExpr>(Sym))
556     return applyBitwiseConstraints(BV, F, Result, SIE);
557 
558   return Result;
559 }
560 
561 // FIXME: Once SValBuilder supports unary minus, we should use SValBuilder to
562 //        obtain the negated symbolic expression instead of constructing the
563 //        symbol manually. This will allow us to support finding ranges of not
564 //        only negated SymSymExpr-type expressions, but also of other, simpler
565 //        expressions which we currently do not know how to negate.
566 const RangeSet*
567 RangeConstraintManager::getRangeForMinusSymbol(ProgramStateRef State,
568                                                SymbolRef Sym) {
569   if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) {
570     if (SSE->getOpcode() == BO_Sub) {
571       QualType T = Sym->getType();
572       SymbolManager &SymMgr = State->getSymbolManager();
573       SymbolRef negSym = SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub,
574                                               SSE->getLHS(), T);
575       if (const RangeSet *negV = State->get<ConstraintRange>(negSym)) {
576         if (T->isUnsignedIntegerOrEnumerationType() ||
577             T->isSignedIntegerOrEnumerationType())
578           return negV;
579       }
580     }
581   }
582   return nullptr;
583 }
584 
585 //===------------------------------------------------------------------------===
586 // assumeSymX methods: protected interface for RangeConstraintManager.
587 //===------------------------------------------------------------------------===/
588 
589 // The syntax for ranges below is mathematical, using [x, y] for closed ranges
590 // and (x, y) for open ranges. These ranges are modular, corresponding with
591 // a common treatment of C integer overflow. This means that these methods
592 // do not have to worry about overflow; RangeSet::Intersect can handle such a
593 // "wraparound" range.
594 // As an example, the range [UINT_MAX-1, 3) contains five values: UINT_MAX-1,
595 // UINT_MAX, 0, 1, and 2.
596 
597 ProgramStateRef
598 RangeConstraintManager::assumeSymNE(ProgramStateRef St, SymbolRef Sym,
599                                     const llvm::APSInt &Int,
600                                     const llvm::APSInt &Adjustment) {
601   // Before we do any real work, see if the value can even show up.
602   APSIntType AdjustmentType(Adjustment);
603   if (AdjustmentType.testInRange(Int, true) != APSIntType::RTR_Within)
604     return St;
605 
606   llvm::APSInt Lower = AdjustmentType.convert(Int) - Adjustment;
607   llvm::APSInt Upper = Lower;
608   --Lower;
609   ++Upper;
610 
611   // [Int-Adjustment+1, Int-Adjustment-1]
612   // Notice that the lower bound is greater than the upper bound.
613   RangeSet New = getRange(St, Sym).Intersect(getBasicVals(), F, Upper, Lower);
614   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
615 }
616 
617 ProgramStateRef
618 RangeConstraintManager::assumeSymEQ(ProgramStateRef St, SymbolRef Sym,
619                                     const llvm::APSInt &Int,
620                                     const llvm::APSInt &Adjustment) {
621   // Before we do any real work, see if the value can even show up.
622   APSIntType AdjustmentType(Adjustment);
623   if (AdjustmentType.testInRange(Int, true) != APSIntType::RTR_Within)
624     return nullptr;
625 
626   // [Int-Adjustment, Int-Adjustment]
627   llvm::APSInt AdjInt = AdjustmentType.convert(Int) - Adjustment;
628   RangeSet New = getRange(St, Sym).Intersect(getBasicVals(), F, AdjInt, AdjInt);
629   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
630 }
631 
632 RangeSet RangeConstraintManager::getSymLTRange(ProgramStateRef St,
633                                                SymbolRef Sym,
634                                                const llvm::APSInt &Int,
635                                                const llvm::APSInt &Adjustment) {
636   // Before we do any real work, see if the value can even show up.
637   APSIntType AdjustmentType(Adjustment);
638   switch (AdjustmentType.testInRange(Int, true)) {
639   case APSIntType::RTR_Below:
640     return F.getEmptySet();
641   case APSIntType::RTR_Within:
642     break;
643   case APSIntType::RTR_Above:
644     return getRange(St, Sym);
645   }
646 
647   // Special case for Int == Min. This is always false.
648   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
649   llvm::APSInt Min = AdjustmentType.getMinValue();
650   if (ComparisonVal == Min)
651     return F.getEmptySet();
652 
653   llvm::APSInt Lower = Min - Adjustment;
654   llvm::APSInt Upper = ComparisonVal - Adjustment;
655   --Upper;
656 
657   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
658 }
659 
660 ProgramStateRef
661 RangeConstraintManager::assumeSymLT(ProgramStateRef St, SymbolRef Sym,
662                                     const llvm::APSInt &Int,
663                                     const llvm::APSInt &Adjustment) {
664   RangeSet New = getSymLTRange(St, Sym, Int, Adjustment);
665   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
666 }
667 
668 RangeSet RangeConstraintManager::getSymGTRange(ProgramStateRef St,
669                                                SymbolRef Sym,
670                                                const llvm::APSInt &Int,
671                                                const llvm::APSInt &Adjustment) {
672   // Before we do any real work, see if the value can even show up.
673   APSIntType AdjustmentType(Adjustment);
674   switch (AdjustmentType.testInRange(Int, true)) {
675   case APSIntType::RTR_Below:
676     return getRange(St, Sym);
677   case APSIntType::RTR_Within:
678     break;
679   case APSIntType::RTR_Above:
680     return F.getEmptySet();
681   }
682 
683   // Special case for Int == Max. This is always false.
684   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
685   llvm::APSInt Max = AdjustmentType.getMaxValue();
686   if (ComparisonVal == Max)
687     return F.getEmptySet();
688 
689   llvm::APSInt Lower = ComparisonVal - Adjustment;
690   llvm::APSInt Upper = Max - Adjustment;
691   ++Lower;
692 
693   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
694 }
695 
696 ProgramStateRef
697 RangeConstraintManager::assumeSymGT(ProgramStateRef St, SymbolRef Sym,
698                                     const llvm::APSInt &Int,
699                                     const llvm::APSInt &Adjustment) {
700   RangeSet New = getSymGTRange(St, Sym, Int, Adjustment);
701   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
702 }
703 
704 RangeSet RangeConstraintManager::getSymGERange(ProgramStateRef St,
705                                                SymbolRef Sym,
706                                                const llvm::APSInt &Int,
707                                                const llvm::APSInt &Adjustment) {
708   // Before we do any real work, see if the value can even show up.
709   APSIntType AdjustmentType(Adjustment);
710   switch (AdjustmentType.testInRange(Int, true)) {
711   case APSIntType::RTR_Below:
712     return getRange(St, Sym);
713   case APSIntType::RTR_Within:
714     break;
715   case APSIntType::RTR_Above:
716     return F.getEmptySet();
717   }
718 
719   // Special case for Int == Min. This is always feasible.
720   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
721   llvm::APSInt Min = AdjustmentType.getMinValue();
722   if (ComparisonVal == Min)
723     return getRange(St, Sym);
724 
725   llvm::APSInt Max = AdjustmentType.getMaxValue();
726   llvm::APSInt Lower = ComparisonVal - Adjustment;
727   llvm::APSInt Upper = Max - Adjustment;
728 
729   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
730 }
731 
732 ProgramStateRef
733 RangeConstraintManager::assumeSymGE(ProgramStateRef St, SymbolRef Sym,
734                                     const llvm::APSInt &Int,
735                                     const llvm::APSInt &Adjustment) {
736   RangeSet New = getSymGERange(St, Sym, Int, Adjustment);
737   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
738 }
739 
740 RangeSet RangeConstraintManager::getSymLERange(
741       llvm::function_ref<RangeSet()> RS,
742       const llvm::APSInt &Int,
743       const llvm::APSInt &Adjustment) {
744   // Before we do any real work, see if the value can even show up.
745   APSIntType AdjustmentType(Adjustment);
746   switch (AdjustmentType.testInRange(Int, true)) {
747   case APSIntType::RTR_Below:
748     return F.getEmptySet();
749   case APSIntType::RTR_Within:
750     break;
751   case APSIntType::RTR_Above:
752     return RS();
753   }
754 
755   // Special case for Int == Max. This is always feasible.
756   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
757   llvm::APSInt Max = AdjustmentType.getMaxValue();
758   if (ComparisonVal == Max)
759     return RS();
760 
761   llvm::APSInt Min = AdjustmentType.getMinValue();
762   llvm::APSInt Lower = Min - Adjustment;
763   llvm::APSInt Upper = ComparisonVal - Adjustment;
764 
765   return RS().Intersect(getBasicVals(), F, Lower, Upper);
766 }
767 
768 RangeSet RangeConstraintManager::getSymLERange(ProgramStateRef St,
769                                                SymbolRef Sym,
770                                                const llvm::APSInt &Int,
771                                                const llvm::APSInt &Adjustment) {
772   return getSymLERange([&] { return getRange(St, Sym); }, Int, Adjustment);
773 }
774 
775 ProgramStateRef
776 RangeConstraintManager::assumeSymLE(ProgramStateRef St, SymbolRef Sym,
777                                     const llvm::APSInt &Int,
778                                     const llvm::APSInt &Adjustment) {
779   RangeSet New = getSymLERange(St, Sym, Int, Adjustment);
780   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
781 }
782 
783 ProgramStateRef RangeConstraintManager::assumeSymWithinInclusiveRange(
784     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
785     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
786   RangeSet New = getSymGERange(State, Sym, From, Adjustment);
787   if (New.isEmpty())
788     return nullptr;
789   RangeSet Out = getSymLERange([&] { return New; }, To, Adjustment);
790   return Out.isEmpty() ? nullptr : State->set<ConstraintRange>(Sym, Out);
791 }
792 
793 ProgramStateRef RangeConstraintManager::assumeSymOutsideInclusiveRange(
794     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
795     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
796   RangeSet RangeLT = getSymLTRange(State, Sym, From, Adjustment);
797   RangeSet RangeGT = getSymGTRange(State, Sym, To, Adjustment);
798   RangeSet New(RangeLT.addRange(F, RangeGT));
799   return New.isEmpty() ? nullptr : State->set<ConstraintRange>(Sym, New);
800 }
801 
802 //===----------------------------------------------------------------------===//
803 // Pretty-printing.
804 //===----------------------------------------------------------------------===//
805 
806 void RangeConstraintManager::printJson(raw_ostream &Out, ProgramStateRef State,
807                                        const char *NL, unsigned int Space,
808                                        bool IsDot) const {
809   ConstraintRangeTy Constraints = State->get<ConstraintRange>();
810 
811   Indent(Out, Space, IsDot) << "\"constraints\": ";
812   if (Constraints.isEmpty()) {
813     Out << "null," << NL;
814     return;
815   }
816 
817   ++Space;
818   Out << '[' << NL;
819   for (ConstraintRangeTy::iterator I = Constraints.begin();
820        I != Constraints.end(); ++I) {
821     Indent(Out, Space, IsDot)
822         << "{ \"symbol\": \"" << I.getKey() << "\", \"range\": \"";
823     I.getData().print(Out);
824     Out << "\" }";
825 
826     if (std::next(I) != Constraints.end())
827       Out << ',';
828     Out << NL;
829   }
830 
831   --Space;
832   Indent(Out, Space, IsDot) << "]," << NL;
833 }
834