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 "clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h"
20 #include "llvm/ADT/FoldingSet.h"
21 #include "llvm/ADT/ImmutableSet.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/Support/Compiler.h"
24 #include "llvm/Support/raw_ostream.h"
25 
26 using namespace clang;
27 using namespace ento;
28 
29 // This class can be extended with other tables which will help to reason
30 // about ranges more precisely.
31 class OperatorRelationsTable {
32   static_assert(BO_LT < BO_GT && BO_GT < BO_LE && BO_LE < BO_GE &&
33                     BO_GE < BO_EQ && BO_EQ < BO_NE,
34                 "This class relies on operators order. Rework it otherwise.");
35 
36 public:
37   enum TriStateKind {
38     False = 0,
39     True,
40     Unknown,
41   };
42 
43 private:
44   // CmpOpTable holds states which represent the corresponding range for
45   // branching an exploded graph. We can reason about the branch if there is
46   // a previously known fact of the existence of a comparison expression with
47   // operands used in the current expression.
48   // E.g. assuming (x < y) is true that means (x != y) is surely true.
49   // if (x previous_operation y)  // <    | !=      | >
50   //   if (x operation y)         // !=   | >       | <
51   //     tristate                 // True | Unknown | False
52   //
53   // CmpOpTable represents next:
54   // __|< |> |<=|>=|==|!=|UnknownX2|
55   // < |1 |0 |* |0 |0 |* |1        |
56   // > |0 |1 |0 |* |0 |* |1        |
57   // <=|1 |0 |1 |* |1 |* |0        |
58   // >=|0 |1 |* |1 |1 |* |0        |
59   // ==|0 |0 |* |* |1 |0 |1        |
60   // !=|1 |1 |* |* |0 |1 |0        |
61   //
62   // Columns stands for a previous operator.
63   // Rows stands for a current operator.
64   // Each row has exactly two `Unknown` cases.
65   // UnknownX2 means that both `Unknown` previous operators are met in code,
66   // and there is a special column for that, for example:
67   // if (x >= y)
68   //   if (x != y)
69   //     if (x <= y)
70   //       False only
71   static constexpr size_t CmpOpCount = BO_NE - BO_LT + 1;
72   const TriStateKind CmpOpTable[CmpOpCount][CmpOpCount + 1] = {
73       // <      >      <=     >=     ==     !=    UnknownX2
74       {True, False, Unknown, False, False, Unknown, True}, // <
75       {False, True, False, Unknown, False, Unknown, True}, // >
76       {True, False, True, Unknown, True, Unknown, False},  // <=
77       {False, True, Unknown, True, True, Unknown, False},  // >=
78       {False, False, Unknown, Unknown, True, False, True}, // ==
79       {True, True, Unknown, Unknown, False, True, False},  // !=
80   };
81 
82   static size_t getIndexFromOp(BinaryOperatorKind OP) {
83     return static_cast<size_t>(OP - BO_LT);
84   }
85 
86 public:
87   constexpr size_t getCmpOpCount() const { return CmpOpCount; }
88 
89   static BinaryOperatorKind getOpFromIndex(size_t Index) {
90     return static_cast<BinaryOperatorKind>(Index + BO_LT);
91   }
92 
93   TriStateKind getCmpOpState(BinaryOperatorKind CurrentOP,
94                              BinaryOperatorKind QueriedOP) const {
95     return CmpOpTable[getIndexFromOp(CurrentOP)][getIndexFromOp(QueriedOP)];
96   }
97 
98   TriStateKind getCmpOpStateForUnknownX2(BinaryOperatorKind CurrentOP) const {
99     return CmpOpTable[getIndexFromOp(CurrentOP)][CmpOpCount];
100   }
101 };
102 //===----------------------------------------------------------------------===//
103 //                           RangeSet implementation
104 //===----------------------------------------------------------------------===//
105 
106 void RangeSet::IntersectInRange(BasicValueFactory &BV, Factory &F,
107                                 const llvm::APSInt &Lower,
108                                 const llvm::APSInt &Upper,
109                                 PrimRangeSet &newRanges,
110                                 PrimRangeSet::iterator &i,
111                                 PrimRangeSet::iterator &e) const {
112   // There are six cases for each range R in the set:
113   //   1. R is entirely before the intersection range.
114   //   2. R is entirely after the intersection range.
115   //   3. R contains the entire intersection range.
116   //   4. R starts before the intersection range and ends in the middle.
117   //   5. R starts in the middle of the intersection range and ends after it.
118   //   6. R is entirely contained in the intersection range.
119   // These correspond to each of the conditions below.
120   for (/* i = begin(), e = end() */; i != e; ++i) {
121     if (i->To() < Lower) {
122       continue;
123     }
124     if (i->From() > Upper) {
125       break;
126     }
127 
128     if (i->Includes(Lower)) {
129       if (i->Includes(Upper)) {
130         newRanges =
131             F.add(newRanges, Range(BV.getValue(Lower), BV.getValue(Upper)));
132         break;
133       } else
134         newRanges = F.add(newRanges, Range(BV.getValue(Lower), i->To()));
135     } else {
136       if (i->Includes(Upper)) {
137         newRanges = F.add(newRanges, Range(i->From(), BV.getValue(Upper)));
138         break;
139       } else
140         newRanges = F.add(newRanges, *i);
141     }
142   }
143 }
144 
145 const llvm::APSInt &RangeSet::getMinValue() const {
146   assert(!isEmpty());
147   return begin()->From();
148 }
149 
150 const llvm::APSInt &RangeSet::getMaxValue() const {
151   assert(!isEmpty());
152   // NOTE: It's a shame that we can't implement 'getMaxValue' without scanning
153   //       the whole tree to get to the last element.
154   //       llvm::ImmutableSet should support decrement for 'end' iterators
155   //       or reverse order iteration.
156   auto It = begin();
157   for (auto End = end(); std::next(It) != End; ++It) {
158   }
159   return It->To();
160 }
161 
162 bool RangeSet::pin(llvm::APSInt &Lower, llvm::APSInt &Upper) const {
163   if (isEmpty()) {
164     // This range is already infeasible.
165     return false;
166   }
167 
168   // This function has nine cases, the cartesian product of range-testing
169   // both the upper and lower bounds against the symbol's type.
170   // Each case requires a different pinning operation.
171   // The function returns false if the described range is entirely outside
172   // the range of values for the associated symbol.
173   APSIntType Type(getMinValue());
174   APSIntType::RangeTestResultKind LowerTest = Type.testInRange(Lower, true);
175   APSIntType::RangeTestResultKind UpperTest = Type.testInRange(Upper, true);
176 
177   switch (LowerTest) {
178   case APSIntType::RTR_Below:
179     switch (UpperTest) {
180     case APSIntType::RTR_Below:
181       // The entire range is outside the symbol's set of possible values.
182       // If this is a conventionally-ordered range, the state is infeasible.
183       if (Lower <= Upper)
184         return false;
185 
186       // However, if the range wraps around, it spans all possible values.
187       Lower = Type.getMinValue();
188       Upper = Type.getMaxValue();
189       break;
190     case APSIntType::RTR_Within:
191       // The range starts below what's possible but ends within it. Pin.
192       Lower = Type.getMinValue();
193       Type.apply(Upper);
194       break;
195     case APSIntType::RTR_Above:
196       // The range spans all possible values for the symbol. Pin.
197       Lower = Type.getMinValue();
198       Upper = Type.getMaxValue();
199       break;
200     }
201     break;
202   case APSIntType::RTR_Within:
203     switch (UpperTest) {
204     case APSIntType::RTR_Below:
205       // The range wraps around, but all lower values are not possible.
206       Type.apply(Lower);
207       Upper = Type.getMaxValue();
208       break;
209     case APSIntType::RTR_Within:
210       // The range may or may not wrap around, but both limits are valid.
211       Type.apply(Lower);
212       Type.apply(Upper);
213       break;
214     case APSIntType::RTR_Above:
215       // The range starts within what's possible but ends above it. Pin.
216       Type.apply(Lower);
217       Upper = Type.getMaxValue();
218       break;
219     }
220     break;
221   case APSIntType::RTR_Above:
222     switch (UpperTest) {
223     case APSIntType::RTR_Below:
224       // The range wraps but is outside the symbol's set of possible values.
225       return false;
226     case APSIntType::RTR_Within:
227       // The range starts above what's possible but ends within it (wrap).
228       Lower = Type.getMinValue();
229       Type.apply(Upper);
230       break;
231     case APSIntType::RTR_Above:
232       // The entire range is outside the symbol's set of possible values.
233       // If this is a conventionally-ordered range, the state is infeasible.
234       if (Lower <= Upper)
235         return false;
236 
237       // However, if the range wraps around, it spans all possible values.
238       Lower = Type.getMinValue();
239       Upper = Type.getMaxValue();
240       break;
241     }
242     break;
243   }
244 
245   return true;
246 }
247 
248 // Returns a set containing the values in the receiving set, intersected with
249 // the closed range [Lower, Upper]. Unlike the Range type, this range uses
250 // modular arithmetic, corresponding to the common treatment of C integer
251 // overflow. Thus, if the Lower bound is greater than the Upper bound, the
252 // range is taken to wrap around. This is equivalent to taking the
253 // intersection with the two ranges [Min, Upper] and [Lower, Max],
254 // or, alternatively, /removing/ all integers between Upper and Lower.
255 RangeSet RangeSet::Intersect(BasicValueFactory &BV, Factory &F,
256                              llvm::APSInt Lower, llvm::APSInt Upper) const {
257   PrimRangeSet newRanges = F.getEmptySet();
258 
259   if (isEmpty() || !pin(Lower, Upper))
260     return newRanges;
261 
262   PrimRangeSet::iterator i = begin(), e = end();
263   if (Lower <= Upper)
264     IntersectInRange(BV, F, Lower, Upper, newRanges, i, e);
265   else {
266     // The order of the next two statements is important!
267     // IntersectInRange() does not reset the iteration state for i and e.
268     // Therefore, the lower range most be handled first.
269     IntersectInRange(BV, F, BV.getMinValue(Upper), Upper, newRanges, i, e);
270     IntersectInRange(BV, F, Lower, BV.getMaxValue(Lower), newRanges, i, e);
271   }
272 
273   return newRanges;
274 }
275 
276 // Returns a set containing the values in the receiving set, intersected with
277 // the range set passed as parameter.
278 RangeSet RangeSet::Intersect(BasicValueFactory &BV, Factory &F,
279                              const RangeSet &Other) const {
280   PrimRangeSet newRanges = F.getEmptySet();
281 
282   for (iterator i = Other.begin(), e = Other.end(); i != e; ++i) {
283     RangeSet newPiece = Intersect(BV, F, i->From(), i->To());
284     for (iterator j = newPiece.begin(), ee = newPiece.end(); j != ee; ++j) {
285       newRanges = F.add(newRanges, *j);
286     }
287   }
288 
289   return newRanges;
290 }
291 
292 // Turn all [A, B] ranges to [-B, -A], when "-" is a C-like unary minus
293 // operation under the values of the type.
294 //
295 // We also handle MIN because applying unary minus to MIN does not change it.
296 // Example 1:
297 // char x = -128;        // -128 is a MIN value in a range of 'char'
298 // char y = -x;          // y: -128
299 // Example 2:
300 // unsigned char x = 0;  // 0 is a MIN value in a range of 'unsigned char'
301 // unsigned char y = -x; // y: 0
302 //
303 // And it makes us to separate the range
304 // like [MIN, N] to [MIN, MIN] U [-N,MAX].
305 // For instance, whole range is {-128..127} and subrange is [-128,-126],
306 // thus [-128,-127,-126,.....] negates to [-128,.....,126,127].
307 //
308 // Negate restores disrupted ranges on bounds,
309 // e.g. [MIN, B] => [MIN, MIN] U [-B, MAX] => [MIN, B].
310 RangeSet RangeSet::Negate(BasicValueFactory &BV, Factory &F) const {
311   PrimRangeSet newRanges = F.getEmptySet();
312 
313   if (isEmpty())
314     return newRanges;
315 
316   const llvm::APSInt sampleValue = getMinValue();
317   const llvm::APSInt &MIN = BV.getMinValue(sampleValue);
318   const llvm::APSInt &MAX = BV.getMaxValue(sampleValue);
319 
320   // Handle a special case for MIN value.
321   iterator i = begin();
322   const llvm::APSInt &from = i->From();
323   const llvm::APSInt &to = i->To();
324   if (from == MIN) {
325     // If [from, to] are [MIN, MAX], then just return the same [MIN, MAX].
326     if (to == MAX) {
327       newRanges = ranges;
328     } else {
329       // Add separate range for the lowest value.
330       newRanges = F.add(newRanges, Range(MIN, MIN));
331       // Skip adding the second range in case when [from, to] are [MIN, MIN].
332       if (to != MIN) {
333         newRanges = F.add(newRanges, Range(BV.getValue(-to), MAX));
334       }
335     }
336     // Skip the first range in the loop.
337     ++i;
338   }
339 
340   // Negate all other ranges.
341   for (iterator e = end(); i != e; ++i) {
342     // Negate int values.
343     const llvm::APSInt &newFrom = BV.getValue(-i->To());
344     const llvm::APSInt &newTo = BV.getValue(-i->From());
345     // Add a negated range.
346     newRanges = F.add(newRanges, Range(newFrom, newTo));
347   }
348 
349   if (newRanges.isSingleton())
350     return newRanges;
351 
352   // Try to find and unite next ranges:
353   // [MIN, MIN] & [MIN + 1, N] => [MIN, N].
354   iterator iter1 = newRanges.begin();
355   iterator iter2 = std::next(iter1);
356 
357   if (iter1->To() == MIN && (iter2->From() - 1) == MIN) {
358     const llvm::APSInt &to = iter2->To();
359     // remove adjacent ranges
360     newRanges = F.remove(newRanges, *iter1);
361     newRanges = F.remove(newRanges, *newRanges.begin());
362     // add united range
363     newRanges = F.add(newRanges, Range(MIN, to));
364   }
365 
366   return newRanges;
367 }
368 
369 RangeSet RangeSet::Delete(BasicValueFactory &BV, Factory &F,
370                           const llvm::APSInt &Point) const {
371   llvm::APSInt Upper = Point;
372   llvm::APSInt Lower = Point;
373 
374   ++Upper;
375   --Lower;
376 
377   // Notice that the lower bound is greater than the upper bound.
378   return Intersect(BV, F, Upper, Lower);
379 }
380 
381 void RangeSet::print(raw_ostream &os) const {
382   bool isFirst = true;
383   os << "{ ";
384   for (iterator i = begin(), e = end(); i != e; ++i) {
385     if (isFirst)
386       isFirst = false;
387     else
388       os << ", ";
389 
390     os << '[' << i->From().toString(10) << ", " << i->To().toString(10)
391        << ']';
392   }
393   os << " }";
394 }
395 
396 REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(SymbolSet, SymbolRef)
397 
398 namespace {
399 class EquivalenceClass;
400 } // end anonymous namespace
401 
402 REGISTER_MAP_WITH_PROGRAMSTATE(ClassMap, SymbolRef, EquivalenceClass)
403 REGISTER_MAP_WITH_PROGRAMSTATE(ClassMembers, EquivalenceClass, SymbolSet)
404 REGISTER_MAP_WITH_PROGRAMSTATE(ConstraintRange, EquivalenceClass, RangeSet)
405 
406 REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(ClassSet, EquivalenceClass)
407 REGISTER_MAP_WITH_PROGRAMSTATE(DisequalityMap, EquivalenceClass, ClassSet)
408 
409 namespace {
410 /// This class encapsulates a set of symbols equal to each other.
411 ///
412 /// The main idea of the approach requiring such classes is in narrowing
413 /// and sharing constraints between symbols within the class.  Also we can
414 /// conclude that there is no practical need in storing constraints for
415 /// every member of the class separately.
416 ///
417 /// Main terminology:
418 ///
419 ///   * "Equivalence class" is an object of this class, which can be efficiently
420 ///     compared to other classes.  It represents the whole class without
421 ///     storing the actual in it.  The members of the class however can be
422 ///     retrieved from the state.
423 ///
424 ///   * "Class members" are the symbols corresponding to the class.  This means
425 ///     that A == B for every member symbols A and B from the class.  Members of
426 ///     each class are stored in the state.
427 ///
428 ///   * "Trivial class" is a class that has and ever had only one same symbol.
429 ///
430 ///   * "Merge operation" merges two classes into one.  It is the main operation
431 ///     to produce non-trivial classes.
432 ///     If, at some point, we can assume that two symbols from two distinct
433 ///     classes are equal, we can merge these classes.
434 class EquivalenceClass : public llvm::FoldingSetNode {
435 public:
436   /// Find equivalence class for the given symbol in the given state.
437   LLVM_NODISCARD static inline EquivalenceClass find(ProgramStateRef State,
438                                                      SymbolRef Sym);
439 
440   /// Merge classes for the given symbols and return a new state.
441   LLVM_NODISCARD static inline ProgramStateRef
442   merge(BasicValueFactory &BV, RangeSet::Factory &F, ProgramStateRef State,
443         SymbolRef First, SymbolRef Second);
444   // Merge this class with the given class and return a new state.
445   LLVM_NODISCARD inline ProgramStateRef merge(BasicValueFactory &BV,
446                                               RangeSet::Factory &F,
447                                               ProgramStateRef State,
448                                               EquivalenceClass Other);
449 
450   /// Return a set of class members for the given state.
451   LLVM_NODISCARD inline SymbolSet getClassMembers(ProgramStateRef State);
452   /// Return true if the current class is trivial in the given state.
453   LLVM_NODISCARD inline bool isTrivial(ProgramStateRef State);
454   /// Return true if the current class is trivial and its only member is dead.
455   LLVM_NODISCARD inline bool isTriviallyDead(ProgramStateRef State,
456                                              SymbolReaper &Reaper);
457 
458   LLVM_NODISCARD static inline ProgramStateRef
459   markDisequal(BasicValueFactory &BV, RangeSet::Factory &F,
460                ProgramStateRef State, SymbolRef First, SymbolRef Second);
461   LLVM_NODISCARD static inline ProgramStateRef
462   markDisequal(BasicValueFactory &BV, RangeSet::Factory &F,
463                ProgramStateRef State, EquivalenceClass First,
464                EquivalenceClass Second);
465   LLVM_NODISCARD inline ProgramStateRef
466   markDisequal(BasicValueFactory &BV, RangeSet::Factory &F,
467                ProgramStateRef State, EquivalenceClass Other) const;
468   LLVM_NODISCARD static inline ClassSet
469   getDisequalClasses(ProgramStateRef State, SymbolRef Sym);
470   LLVM_NODISCARD inline ClassSet
471   getDisequalClasses(ProgramStateRef State) const;
472   LLVM_NODISCARD inline ClassSet
473   getDisequalClasses(DisequalityMapTy Map, ClassSet::Factory &Factory) const;
474 
475   LLVM_NODISCARD static inline Optional<bool>
476   areEqual(ProgramStateRef State, SymbolRef First, SymbolRef Second);
477 
478   /// Check equivalence data for consistency.
479   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
480   isClassDataConsistent(ProgramStateRef State);
481 
482   LLVM_NODISCARD QualType getType() const {
483     return getRepresentativeSymbol()->getType();
484   }
485 
486   EquivalenceClass() = delete;
487   EquivalenceClass(const EquivalenceClass &) = default;
488   EquivalenceClass &operator=(const EquivalenceClass &) = delete;
489   EquivalenceClass(EquivalenceClass &&) = default;
490   EquivalenceClass &operator=(EquivalenceClass &&) = delete;
491 
492   bool operator==(const EquivalenceClass &Other) const {
493     return ID == Other.ID;
494   }
495   bool operator<(const EquivalenceClass &Other) const { return ID < Other.ID; }
496   bool operator!=(const EquivalenceClass &Other) const {
497     return !operator==(Other);
498   }
499 
500   static void Profile(llvm::FoldingSetNodeID &ID, uintptr_t CID) {
501     ID.AddInteger(CID);
502   }
503 
504   void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, this->ID); }
505 
506 private:
507   /* implicit */ EquivalenceClass(SymbolRef Sym)
508       : ID(reinterpret_cast<uintptr_t>(Sym)) {}
509 
510   /// This function is intended to be used ONLY within the class.
511   /// The fact that ID is a pointer to a symbol is an implementation detail
512   /// and should stay that way.
513   /// In the current implementation, we use it to retrieve the only member
514   /// of the trivial class.
515   SymbolRef getRepresentativeSymbol() const {
516     return reinterpret_cast<SymbolRef>(ID);
517   }
518   static inline SymbolSet::Factory &getMembersFactory(ProgramStateRef State);
519 
520   inline ProgramStateRef mergeImpl(BasicValueFactory &BV, RangeSet::Factory &F,
521                                    ProgramStateRef State, SymbolSet Members,
522                                    EquivalenceClass Other,
523                                    SymbolSet OtherMembers);
524   static inline void
525   addToDisequalityInfo(DisequalityMapTy &Info, ConstraintRangeTy &Constraints,
526                        BasicValueFactory &BV, RangeSet::Factory &F,
527                        ProgramStateRef State, EquivalenceClass First,
528                        EquivalenceClass Second);
529 
530   /// This is a unique identifier of the class.
531   uintptr_t ID;
532 };
533 
534 //===----------------------------------------------------------------------===//
535 //                             Constraint functions
536 //===----------------------------------------------------------------------===//
537 
538 LLVM_NODISCARD inline const RangeSet *getConstraint(ProgramStateRef State,
539                                                     EquivalenceClass Class) {
540   return State->get<ConstraintRange>(Class);
541 }
542 
543 LLVM_NODISCARD inline const RangeSet *getConstraint(ProgramStateRef State,
544                                                     SymbolRef Sym) {
545   return getConstraint(State, EquivalenceClass::find(State, Sym));
546 }
547 
548 //===----------------------------------------------------------------------===//
549 //                       Equality/diseqiality abstraction
550 //===----------------------------------------------------------------------===//
551 
552 /// A small helper structure representing symbolic equality.
553 ///
554 /// Equality check can have different forms (like a == b or a - b) and this
555 /// class encapsulates those away if the only thing the user wants to check -
556 /// whether it's equality/diseqiality or not and have an easy access to the
557 /// compared symbols.
558 struct EqualityInfo {
559 public:
560   SymbolRef Left, Right;
561   // true for equality and false for disequality.
562   bool IsEquality = true;
563 
564   void invert() { IsEquality = !IsEquality; }
565   /// Extract equality information from the given symbol and the constants.
566   ///
567   /// This function assumes the following expression Sym + Adjustment != Int.
568   /// It is a default because the most widespread case of the equality check
569   /// is (A == B) + 0 != 0.
570   static Optional<EqualityInfo> extract(SymbolRef Sym, const llvm::APSInt &Int,
571                                         const llvm::APSInt &Adjustment) {
572     // As of now, the only equality form supported is Sym + 0 != 0.
573     if (!Int.isNullValue() || !Adjustment.isNullValue())
574       return llvm::None;
575 
576     return extract(Sym);
577   }
578   /// Extract equality information from the given symbol.
579   static Optional<EqualityInfo> extract(SymbolRef Sym) {
580     return EqualityExtractor().Visit(Sym);
581   }
582 
583 private:
584   class EqualityExtractor
585       : public SymExprVisitor<EqualityExtractor, Optional<EqualityInfo>> {
586   public:
587     Optional<EqualityInfo> VisitSymSymExpr(const SymSymExpr *Sym) const {
588       switch (Sym->getOpcode()) {
589       case BO_Sub:
590         // This case is: A - B != 0 -> disequality check.
591         return EqualityInfo{Sym->getLHS(), Sym->getRHS(), false};
592       case BO_EQ:
593         // This case is: A == B != 0 -> equality check.
594         return EqualityInfo{Sym->getLHS(), Sym->getRHS(), true};
595       case BO_NE:
596         // This case is: A != B != 0 -> diseqiality check.
597         return EqualityInfo{Sym->getLHS(), Sym->getRHS(), false};
598       default:
599         return llvm::None;
600       }
601     }
602   };
603 };
604 
605 //===----------------------------------------------------------------------===//
606 //                            Intersection functions
607 //===----------------------------------------------------------------------===//
608 
609 template <class SecondTy, class... RestTy>
610 LLVM_NODISCARD inline RangeSet intersect(BasicValueFactory &BV,
611                                          RangeSet::Factory &F, RangeSet Head,
612                                          SecondTy Second, RestTy... Tail);
613 
614 template <class... RangeTy> struct IntersectionTraits;
615 
616 template <class... TailTy> struct IntersectionTraits<RangeSet, TailTy...> {
617   // Found RangeSet, no need to check any further
618   using Type = RangeSet;
619 };
620 
621 template <> struct IntersectionTraits<> {
622   // We ran out of types, and we didn't find any RangeSet, so the result should
623   // be optional.
624   using Type = Optional<RangeSet>;
625 };
626 
627 template <class OptionalOrPointer, class... TailTy>
628 struct IntersectionTraits<OptionalOrPointer, TailTy...> {
629   // If current type is Optional or a raw pointer, we should keep looking.
630   using Type = typename IntersectionTraits<TailTy...>::Type;
631 };
632 
633 template <class EndTy>
634 LLVM_NODISCARD inline EndTy intersect(BasicValueFactory &BV,
635                                       RangeSet::Factory &F, EndTy End) {
636   // If the list contains only RangeSet or Optional<RangeSet>, simply return
637   // that range set.
638   return End;
639 }
640 
641 LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED inline Optional<RangeSet>
642 intersect(BasicValueFactory &BV, RangeSet::Factory &F, const RangeSet *End) {
643   // This is an extraneous conversion from a raw pointer into Optional<RangeSet>
644   if (End) {
645     return *End;
646   }
647   return llvm::None;
648 }
649 
650 template <class... RestTy>
651 LLVM_NODISCARD inline RangeSet intersect(BasicValueFactory &BV,
652                                          RangeSet::Factory &F, RangeSet Head,
653                                          RangeSet Second, RestTy... Tail) {
654   // Here we call either the <RangeSet,RangeSet,...> or <RangeSet,...> version
655   // of the function and can be sure that the result is RangeSet.
656   return intersect(BV, F, Head.Intersect(BV, F, Second), Tail...);
657 }
658 
659 template <class SecondTy, class... RestTy>
660 LLVM_NODISCARD inline RangeSet intersect(BasicValueFactory &BV,
661                                          RangeSet::Factory &F, RangeSet Head,
662                                          SecondTy Second, RestTy... Tail) {
663   if (Second) {
664     // Here we call the <RangeSet,RangeSet,...> version of the function...
665     return intersect(BV, F, Head, *Second, Tail...);
666   }
667   // ...and here it is either <RangeSet,RangeSet,...> or <RangeSet,...>, which
668   // means that the result is definitely RangeSet.
669   return intersect(BV, F, Head, Tail...);
670 }
671 
672 /// Main generic intersect function.
673 /// It intersects all of the given range sets.  If some of the given arguments
674 /// don't hold a range set (nullptr or llvm::None), the function will skip them.
675 ///
676 /// Available representations for the arguments are:
677 ///   * RangeSet
678 ///   * Optional<RangeSet>
679 ///   * RangeSet *
680 /// Pointer to a RangeSet is automatically assumed to be nullable and will get
681 /// checked as well as the optional version.  If this behaviour is undesired,
682 /// please dereference the pointer in the call.
683 ///
684 /// Return type depends on the arguments' types.  If we can be sure in compile
685 /// time that there will be a range set as a result, the returning type is
686 /// simply RangeSet, in other cases we have to back off to Optional<RangeSet>.
687 ///
688 /// Please, prefer optional range sets to raw pointers.  If the last argument is
689 /// a raw pointer and all previous arguments are None, it will cost one
690 /// additional check to convert RangeSet * into Optional<RangeSet>.
691 template <class HeadTy, class SecondTy, class... RestTy>
692 LLVM_NODISCARD inline
693     typename IntersectionTraits<HeadTy, SecondTy, RestTy...>::Type
694     intersect(BasicValueFactory &BV, RangeSet::Factory &F, HeadTy Head,
695               SecondTy Second, RestTy... Tail) {
696   if (Head) {
697     return intersect(BV, F, *Head, Second, Tail...);
698   }
699   return intersect(BV, F, Second, Tail...);
700 }
701 
702 //===----------------------------------------------------------------------===//
703 //                           Symbolic reasoning logic
704 //===----------------------------------------------------------------------===//
705 
706 /// A little component aggregating all of the reasoning we have about
707 /// the ranges of symbolic expressions.
708 ///
709 /// Even when we don't know the exact values of the operands, we still
710 /// can get a pretty good estimate of the result's range.
711 class SymbolicRangeInferrer
712     : public SymExprVisitor<SymbolicRangeInferrer, RangeSet> {
713 public:
714   template <class SourceType>
715   static RangeSet inferRange(BasicValueFactory &BV, RangeSet::Factory &F,
716                              ProgramStateRef State, SourceType Origin) {
717     SymbolicRangeInferrer Inferrer(BV, F, State);
718     return Inferrer.infer(Origin);
719   }
720 
721   RangeSet VisitSymExpr(SymbolRef Sym) {
722     // If we got to this function, the actual type of the symbolic
723     // expression is not supported for advanced inference.
724     // In this case, we simply backoff to the default "let's simply
725     // infer the range from the expression's type".
726     return infer(Sym->getType());
727   }
728 
729   RangeSet VisitSymIntExpr(const SymIntExpr *Sym) {
730     return VisitBinaryOperator(Sym);
731   }
732 
733   RangeSet VisitIntSymExpr(const IntSymExpr *Sym) {
734     return VisitBinaryOperator(Sym);
735   }
736 
737   RangeSet VisitSymSymExpr(const SymSymExpr *Sym) {
738     return VisitBinaryOperator(Sym);
739   }
740 
741 private:
742   SymbolicRangeInferrer(BasicValueFactory &BV, RangeSet::Factory &F,
743                         ProgramStateRef S)
744       : ValueFactory(BV), RangeFactory(F), State(S) {}
745 
746   /// Infer range information from the given integer constant.
747   ///
748   /// It's not a real "inference", but is here for operating with
749   /// sub-expressions in a more polymorphic manner.
750   RangeSet inferAs(const llvm::APSInt &Val, QualType) {
751     return {RangeFactory, Val};
752   }
753 
754   /// Infer range information from symbol in the context of the given type.
755   RangeSet inferAs(SymbolRef Sym, QualType DestType) {
756     QualType ActualType = Sym->getType();
757     // Check that we can reason about the symbol at all.
758     if (ActualType->isIntegralOrEnumerationType() ||
759         Loc::isLocType(ActualType)) {
760       return infer(Sym);
761     }
762     // Otherwise, let's simply infer from the destination type.
763     // We couldn't figure out nothing else about that expression.
764     return infer(DestType);
765   }
766 
767   RangeSet infer(SymbolRef Sym) {
768     if (Optional<RangeSet> ConstraintBasedRange = intersect(
769             ValueFactory, RangeFactory, getConstraint(State, Sym),
770             // If Sym is a difference of symbols A - B, then maybe we have range
771             // set stored for B - A.
772             //
773             // If we have range set stored for both A - B and B - A then
774             // calculate the effective range set by intersecting the range set
775             // for A - B and the negated range set of B - A.
776             getRangeForNegatedSub(Sym), getRangeForEqualities(Sym))) {
777       return *ConstraintBasedRange;
778     }
779 
780     // If Sym is a comparison expression (except <=>),
781     // find any other comparisons with the same operands.
782     // See function description.
783     if (Optional<RangeSet> CmpRangeSet = getRangeForComparisonSymbol(Sym)) {
784       return *CmpRangeSet;
785     }
786 
787     return Visit(Sym);
788   }
789 
790   RangeSet infer(EquivalenceClass Class) {
791     if (const RangeSet *AssociatedConstraint = getConstraint(State, Class))
792       return *AssociatedConstraint;
793 
794     return infer(Class.getType());
795   }
796 
797   /// Infer range information solely from the type.
798   RangeSet infer(QualType T) {
799     // Lazily generate a new RangeSet representing all possible values for the
800     // given symbol type.
801     RangeSet Result(RangeFactory, ValueFactory.getMinValue(T),
802                     ValueFactory.getMaxValue(T));
803 
804     // References are known to be non-zero.
805     if (T->isReferenceType())
806       return assumeNonZero(Result, T);
807 
808     return Result;
809   }
810 
811   template <class BinarySymExprTy>
812   RangeSet VisitBinaryOperator(const BinarySymExprTy *Sym) {
813     // TODO #1: VisitBinaryOperator implementation might not make a good
814     // use of the inferred ranges.  In this case, we might be calculating
815     // everything for nothing.  This being said, we should introduce some
816     // sort of laziness mechanism here.
817     //
818     // TODO #2: We didn't go into the nested expressions before, so it
819     // might cause us spending much more time doing the inference.
820     // This can be a problem for deeply nested expressions that are
821     // involved in conditions and get tested continuously.  We definitely
822     // need to address this issue and introduce some sort of caching
823     // in here.
824     QualType ResultType = Sym->getType();
825     return VisitBinaryOperator(inferAs(Sym->getLHS(), ResultType),
826                                Sym->getOpcode(),
827                                inferAs(Sym->getRHS(), ResultType), ResultType);
828   }
829 
830   RangeSet VisitBinaryOperator(RangeSet LHS, BinaryOperator::Opcode Op,
831                                RangeSet RHS, QualType T) {
832     switch (Op) {
833     case BO_Or:
834       return VisitBinaryOperator<BO_Or>(LHS, RHS, T);
835     case BO_And:
836       return VisitBinaryOperator<BO_And>(LHS, RHS, T);
837     case BO_Rem:
838       return VisitBinaryOperator<BO_Rem>(LHS, RHS, T);
839     default:
840       return infer(T);
841     }
842   }
843 
844   //===----------------------------------------------------------------------===//
845   //                         Ranges and operators
846   //===----------------------------------------------------------------------===//
847 
848   /// Return a rough approximation of the given range set.
849   ///
850   /// For the range set:
851   ///   { [x_0, y_0], [x_1, y_1], ... , [x_N, y_N] }
852   /// it will return the range [x_0, y_N].
853   static Range fillGaps(RangeSet Origin) {
854     assert(!Origin.isEmpty());
855     return {Origin.getMinValue(), Origin.getMaxValue()};
856   }
857 
858   /// Try to convert given range into the given type.
859   ///
860   /// It will return llvm::None only when the trivial conversion is possible.
861   llvm::Optional<Range> convert(const Range &Origin, APSIntType To) {
862     if (To.testInRange(Origin.From(), false) != APSIntType::RTR_Within ||
863         To.testInRange(Origin.To(), false) != APSIntType::RTR_Within) {
864       return llvm::None;
865     }
866     return Range(ValueFactory.Convert(To, Origin.From()),
867                  ValueFactory.Convert(To, Origin.To()));
868   }
869 
870   template <BinaryOperator::Opcode Op>
871   RangeSet VisitBinaryOperator(RangeSet LHS, RangeSet RHS, QualType T) {
872     // We should propagate information about unfeasbility of one of the
873     // operands to the resulting range.
874     if (LHS.isEmpty() || RHS.isEmpty()) {
875       return RangeFactory.getEmptySet();
876     }
877 
878     Range CoarseLHS = fillGaps(LHS);
879     Range CoarseRHS = fillGaps(RHS);
880 
881     APSIntType ResultType = ValueFactory.getAPSIntType(T);
882 
883     // We need to convert ranges to the resulting type, so we can compare values
884     // and combine them in a meaningful (in terms of the given operation) way.
885     auto ConvertedCoarseLHS = convert(CoarseLHS, ResultType);
886     auto ConvertedCoarseRHS = convert(CoarseRHS, ResultType);
887 
888     // It is hard to reason about ranges when conversion changes
889     // borders of the ranges.
890     if (!ConvertedCoarseLHS || !ConvertedCoarseRHS) {
891       return infer(T);
892     }
893 
894     return VisitBinaryOperator<Op>(*ConvertedCoarseLHS, *ConvertedCoarseRHS, T);
895   }
896 
897   template <BinaryOperator::Opcode Op>
898   RangeSet VisitBinaryOperator(Range LHS, Range RHS, QualType T) {
899     return infer(T);
900   }
901 
902   /// Return a symmetrical range for the given range and type.
903   ///
904   /// If T is signed, return the smallest range [-x..x] that covers the original
905   /// range, or [-min(T), max(T)] if the aforementioned symmetric range doesn't
906   /// exist due to original range covering min(T)).
907   ///
908   /// If T is unsigned, return the smallest range [0..x] that covers the
909   /// original range.
910   Range getSymmetricalRange(Range Origin, QualType T) {
911     APSIntType RangeType = ValueFactory.getAPSIntType(T);
912 
913     if (RangeType.isUnsigned()) {
914       return Range(ValueFactory.getMinValue(RangeType), Origin.To());
915     }
916 
917     if (Origin.From().isMinSignedValue()) {
918       // If mini is a minimal signed value, absolute value of it is greater
919       // than the maximal signed value.  In order to avoid these
920       // complications, we simply return the whole range.
921       return {ValueFactory.getMinValue(RangeType),
922               ValueFactory.getMaxValue(RangeType)};
923     }
924 
925     // At this point, we are sure that the type is signed and we can safely
926     // use unary - operator.
927     //
928     // While calculating absolute maximum, we can use the following formula
929     // because of these reasons:
930     //   * If From >= 0 then To >= From and To >= -From.
931     //     AbsMax == To == max(To, -From)
932     //   * If To <= 0 then -From >= -To and -From >= From.
933     //     AbsMax == -From == max(-From, To)
934     //   * Otherwise, From <= 0, To >= 0, and
935     //     AbsMax == max(abs(From), abs(To))
936     llvm::APSInt AbsMax = std::max(-Origin.From(), Origin.To());
937 
938     // Intersection is guaranteed to be non-empty.
939     return {ValueFactory.getValue(-AbsMax), ValueFactory.getValue(AbsMax)};
940   }
941 
942   /// Return a range set subtracting zero from \p Domain.
943   RangeSet assumeNonZero(RangeSet Domain, QualType T) {
944     APSIntType IntType = ValueFactory.getAPSIntType(T);
945     return Domain.Delete(ValueFactory, RangeFactory, IntType.getZeroValue());
946   }
947 
948   // FIXME: Once SValBuilder supports unary minus, we should use SValBuilder to
949   //        obtain the negated symbolic expression instead of constructing the
950   //        symbol manually. This will allow us to support finding ranges of not
951   //        only negated SymSymExpr-type expressions, but also of other, simpler
952   //        expressions which we currently do not know how to negate.
953   Optional<RangeSet> getRangeForNegatedSub(SymbolRef Sym) {
954     if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) {
955       if (SSE->getOpcode() == BO_Sub) {
956         QualType T = Sym->getType();
957 
958         // Do not negate unsigned ranges
959         if (!T->isUnsignedIntegerOrEnumerationType() &&
960             !T->isSignedIntegerOrEnumerationType())
961           return llvm::None;
962 
963         SymbolManager &SymMgr = State->getSymbolManager();
964         SymbolRef NegatedSym =
965             SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub, SSE->getLHS(), T);
966 
967         if (const RangeSet *NegatedRange = getConstraint(State, NegatedSym)) {
968           return NegatedRange->Negate(ValueFactory, RangeFactory);
969         }
970       }
971     }
972     return llvm::None;
973   }
974 
975   // Returns ranges only for binary comparison operators (except <=>)
976   // when left and right operands are symbolic values.
977   // Finds any other comparisons with the same operands.
978   // Then do logical calculations and refuse impossible branches.
979   // E.g. (x < y) and (x > y) at the same time are impossible.
980   // E.g. (x >= y) and (x != y) at the same time makes (x > y) true only.
981   // E.g. (x == y) and (y == x) are just reversed but the same.
982   // It covers all possible combinations (see CmpOpTable description).
983   // Note that `x` and `y` can also stand for subexpressions,
984   // not only for actual symbols.
985   Optional<RangeSet> getRangeForComparisonSymbol(SymbolRef Sym) {
986     const auto *SSE = dyn_cast<SymSymExpr>(Sym);
987     if (!SSE)
988       return llvm::None;
989 
990     BinaryOperatorKind CurrentOP = SSE->getOpcode();
991 
992     // We currently do not support <=> (C++20).
993     if (!BinaryOperator::isComparisonOp(CurrentOP) || (CurrentOP == BO_Cmp))
994       return llvm::None;
995 
996     static const OperatorRelationsTable CmpOpTable{};
997 
998     const SymExpr *LHS = SSE->getLHS();
999     const SymExpr *RHS = SSE->getRHS();
1000     QualType T = SSE->getType();
1001 
1002     SymbolManager &SymMgr = State->getSymbolManager();
1003 
1004     int UnknownStates = 0;
1005 
1006     // Loop goes through all of the columns exept the last one ('UnknownX2').
1007     // We treat `UnknownX2` column separately at the end of the loop body.
1008     for (size_t i = 0; i < CmpOpTable.getCmpOpCount(); ++i) {
1009 
1010       // Let's find an expression e.g. (x < y).
1011       BinaryOperatorKind QueriedOP = OperatorRelationsTable::getOpFromIndex(i);
1012       const SymSymExpr *SymSym = SymMgr.getSymSymExpr(LHS, QueriedOP, RHS, T);
1013       const RangeSet *QueriedRangeSet = getConstraint(State, SymSym);
1014 
1015       // If ranges were not previously found,
1016       // try to find a reversed expression (y > x).
1017       if (!QueriedRangeSet) {
1018         const BinaryOperatorKind ROP =
1019             BinaryOperator::reverseComparisonOp(QueriedOP);
1020         SymSym = SymMgr.getSymSymExpr(RHS, ROP, LHS, T);
1021         QueriedRangeSet = getConstraint(State, SymSym);
1022       }
1023 
1024       if (!QueriedRangeSet || QueriedRangeSet->isEmpty())
1025         continue;
1026 
1027       const llvm::APSInt *ConcreteValue = QueriedRangeSet->getConcreteValue();
1028       const bool isInFalseBranch =
1029           ConcreteValue ? (*ConcreteValue == 0) : false;
1030 
1031       // If it is a false branch, we shall be guided by opposite operator,
1032       // because the table is made assuming we are in the true branch.
1033       // E.g. when (x <= y) is false, then (x > y) is true.
1034       if (isInFalseBranch)
1035         QueriedOP = BinaryOperator::negateComparisonOp(QueriedOP);
1036 
1037       OperatorRelationsTable::TriStateKind BranchState =
1038           CmpOpTable.getCmpOpState(CurrentOP, QueriedOP);
1039 
1040       if (BranchState == OperatorRelationsTable::Unknown) {
1041         if (++UnknownStates == 2)
1042           // If we met both Unknown states.
1043           // if (x <= y)    // assume true
1044           //   if (x != y)  // assume true
1045           //     if (x < y) // would be also true
1046           // Get a state from `UnknownX2` column.
1047           BranchState = CmpOpTable.getCmpOpStateForUnknownX2(CurrentOP);
1048         else
1049           continue;
1050       }
1051 
1052       return (BranchState == OperatorRelationsTable::True) ? getTrueRange(T)
1053                                                            : getFalseRange(T);
1054     }
1055 
1056     return llvm::None;
1057   }
1058 
1059   Optional<RangeSet> getRangeForEqualities(SymbolRef Sym) {
1060     Optional<EqualityInfo> Equality = EqualityInfo::extract(Sym);
1061 
1062     if (!Equality)
1063       return llvm::None;
1064 
1065     if (Optional<bool> AreEqual = EquivalenceClass::areEqual(
1066             State, Equality->Left, Equality->Right)) {
1067       if (*AreEqual == Equality->IsEquality) {
1068         return getTrueRange(Sym->getType());
1069       }
1070       return getFalseRange(Sym->getType());
1071     }
1072 
1073     return llvm::None;
1074   }
1075 
1076   RangeSet getTrueRange(QualType T) {
1077     RangeSet TypeRange = infer(T);
1078     return assumeNonZero(TypeRange, T);
1079   }
1080 
1081   RangeSet getFalseRange(QualType T) {
1082     const llvm::APSInt &Zero = ValueFactory.getValue(0, T);
1083     return RangeSet(RangeFactory, Zero);
1084   }
1085 
1086   BasicValueFactory &ValueFactory;
1087   RangeSet::Factory &RangeFactory;
1088   ProgramStateRef State;
1089 };
1090 
1091 //===----------------------------------------------------------------------===//
1092 //               Range-based reasoning about symbolic operations
1093 //===----------------------------------------------------------------------===//
1094 
1095 template <>
1096 RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_Or>(Range LHS, Range RHS,
1097                                                            QualType T) {
1098   APSIntType ResultType = ValueFactory.getAPSIntType(T);
1099   llvm::APSInt Zero = ResultType.getZeroValue();
1100 
1101   bool IsLHSPositiveOrZero = LHS.From() >= Zero;
1102   bool IsRHSPositiveOrZero = RHS.From() >= Zero;
1103 
1104   bool IsLHSNegative = LHS.To() < Zero;
1105   bool IsRHSNegative = RHS.To() < Zero;
1106 
1107   // Check if both ranges have the same sign.
1108   if ((IsLHSPositiveOrZero && IsRHSPositiveOrZero) ||
1109       (IsLHSNegative && IsRHSNegative)) {
1110     // The result is definitely greater or equal than any of the operands.
1111     const llvm::APSInt &Min = std::max(LHS.From(), RHS.From());
1112 
1113     // We estimate maximal value for positives as the maximal value for the
1114     // given type.  For negatives, we estimate it with -1 (e.g. 0x11111111).
1115     //
1116     // TODO: We basically, limit the resulting range from below, but don't do
1117     //       anything with the upper bound.
1118     //
1119     //       For positive operands, it can be done as follows: for the upper
1120     //       bound of LHS and RHS we calculate the most significant bit set.
1121     //       Let's call it the N-th bit.  Then we can estimate the maximal
1122     //       number to be 2^(N+1)-1, i.e. the number with all the bits up to
1123     //       the N-th bit set.
1124     const llvm::APSInt &Max = IsLHSNegative
1125                                   ? ValueFactory.getValue(--Zero)
1126                                   : ValueFactory.getMaxValue(ResultType);
1127 
1128     return {RangeFactory, ValueFactory.getValue(Min), Max};
1129   }
1130 
1131   // Otherwise, let's check if at least one of the operands is negative.
1132   if (IsLHSNegative || IsRHSNegative) {
1133     // This means that the result is definitely negative as well.
1134     return {RangeFactory, ValueFactory.getMinValue(ResultType),
1135             ValueFactory.getValue(--Zero)};
1136   }
1137 
1138   RangeSet DefaultRange = infer(T);
1139 
1140   // It is pretty hard to reason about operands with different signs
1141   // (and especially with possibly different signs).  We simply check if it
1142   // can be zero.  In order to conclude that the result could not be zero,
1143   // at least one of the operands should be definitely not zero itself.
1144   if (!LHS.Includes(Zero) || !RHS.Includes(Zero)) {
1145     return assumeNonZero(DefaultRange, T);
1146   }
1147 
1148   // Nothing much else to do here.
1149   return DefaultRange;
1150 }
1151 
1152 template <>
1153 RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_And>(Range LHS,
1154                                                             Range RHS,
1155                                                             QualType T) {
1156   APSIntType ResultType = ValueFactory.getAPSIntType(T);
1157   llvm::APSInt Zero = ResultType.getZeroValue();
1158 
1159   bool IsLHSPositiveOrZero = LHS.From() >= Zero;
1160   bool IsRHSPositiveOrZero = RHS.From() >= Zero;
1161 
1162   bool IsLHSNegative = LHS.To() < Zero;
1163   bool IsRHSNegative = RHS.To() < Zero;
1164 
1165   // Check if both ranges have the same sign.
1166   if ((IsLHSPositiveOrZero && IsRHSPositiveOrZero) ||
1167       (IsLHSNegative && IsRHSNegative)) {
1168     // The result is definitely less or equal than any of the operands.
1169     const llvm::APSInt &Max = std::min(LHS.To(), RHS.To());
1170 
1171     // We conservatively estimate lower bound to be the smallest positive
1172     // or negative value corresponding to the sign of the operands.
1173     const llvm::APSInt &Min = IsLHSNegative
1174                                   ? ValueFactory.getMinValue(ResultType)
1175                                   : ValueFactory.getValue(Zero);
1176 
1177     return {RangeFactory, Min, Max};
1178   }
1179 
1180   // Otherwise, let's check if at least one of the operands is positive.
1181   if (IsLHSPositiveOrZero || IsRHSPositiveOrZero) {
1182     // This makes result definitely positive.
1183     //
1184     // We can also reason about a maximal value by finding the maximal
1185     // value of the positive operand.
1186     const llvm::APSInt &Max = IsLHSPositiveOrZero ? LHS.To() : RHS.To();
1187 
1188     // The minimal value on the other hand is much harder to reason about.
1189     // The only thing we know for sure is that the result is positive.
1190     return {RangeFactory, ValueFactory.getValue(Zero),
1191             ValueFactory.getValue(Max)};
1192   }
1193 
1194   // Nothing much else to do here.
1195   return infer(T);
1196 }
1197 
1198 template <>
1199 RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_Rem>(Range LHS,
1200                                                             Range RHS,
1201                                                             QualType T) {
1202   llvm::APSInt Zero = ValueFactory.getAPSIntType(T).getZeroValue();
1203 
1204   Range ConservativeRange = getSymmetricalRange(RHS, T);
1205 
1206   llvm::APSInt Max = ConservativeRange.To();
1207   llvm::APSInt Min = ConservativeRange.From();
1208 
1209   if (Max == Zero) {
1210     // It's an undefined behaviour to divide by 0 and it seems like we know
1211     // for sure that RHS is 0.  Let's say that the resulting range is
1212     // simply infeasible for that matter.
1213     return RangeFactory.getEmptySet();
1214   }
1215 
1216   // At this point, our conservative range is closed.  The result, however,
1217   // couldn't be greater than the RHS' maximal absolute value.  Because of
1218   // this reason, we turn the range into open (or half-open in case of
1219   // unsigned integers).
1220   //
1221   // While we operate on integer values, an open interval (a, b) can be easily
1222   // represented by the closed interval [a + 1, b - 1].  And this is exactly
1223   // what we do next.
1224   //
1225   // If we are dealing with unsigned case, we shouldn't move the lower bound.
1226   if (Min.isSigned()) {
1227     ++Min;
1228   }
1229   --Max;
1230 
1231   bool IsLHSPositiveOrZero = LHS.From() >= Zero;
1232   bool IsRHSPositiveOrZero = RHS.From() >= Zero;
1233 
1234   // Remainder operator results with negative operands is implementation
1235   // defined.  Positive cases are much easier to reason about though.
1236   if (IsLHSPositiveOrZero && IsRHSPositiveOrZero) {
1237     // If maximal value of LHS is less than maximal value of RHS,
1238     // the result won't get greater than LHS.To().
1239     Max = std::min(LHS.To(), Max);
1240     // We want to check if it is a situation similar to the following:
1241     //
1242     // <------------|---[  LHS  ]--------[  RHS  ]----->
1243     //  -INF        0                              +INF
1244     //
1245     // In this situation, we can conclude that (LHS / RHS) == 0 and
1246     // (LHS % RHS) == LHS.
1247     Min = LHS.To() < RHS.From() ? LHS.From() : Zero;
1248   }
1249 
1250   // Nevertheless, the symmetrical range for RHS is a conservative estimate
1251   // for any sign of either LHS, or RHS.
1252   return {RangeFactory, ValueFactory.getValue(Min), ValueFactory.getValue(Max)};
1253 }
1254 
1255 //===----------------------------------------------------------------------===//
1256 //                  Constraint manager implementation details
1257 //===----------------------------------------------------------------------===//
1258 
1259 class RangeConstraintManager : public RangedConstraintManager {
1260 public:
1261   RangeConstraintManager(ExprEngine *EE, SValBuilder &SVB)
1262       : RangedConstraintManager(EE, SVB) {}
1263 
1264   //===------------------------------------------------------------------===//
1265   // Implementation for interface from ConstraintManager.
1266   //===------------------------------------------------------------------===//
1267 
1268   bool haveEqualConstraints(ProgramStateRef S1,
1269                             ProgramStateRef S2) const override {
1270     // NOTE: ClassMembers are as simple as back pointers for ClassMap,
1271     //       so comparing constraint ranges and class maps should be
1272     //       sufficient.
1273     return S1->get<ConstraintRange>() == S2->get<ConstraintRange>() &&
1274            S1->get<ClassMap>() == S2->get<ClassMap>();
1275   }
1276 
1277   bool canReasonAbout(SVal X) const override;
1278 
1279   ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
1280 
1281   const llvm::APSInt *getSymVal(ProgramStateRef State,
1282                                 SymbolRef Sym) const override;
1283 
1284   ProgramStateRef removeDeadBindings(ProgramStateRef State,
1285                                      SymbolReaper &SymReaper) override;
1286 
1287   void printJson(raw_ostream &Out, ProgramStateRef State, const char *NL = "\n",
1288                  unsigned int Space = 0, bool IsDot = false) const override;
1289 
1290   //===------------------------------------------------------------------===//
1291   // Implementation for interface from RangedConstraintManager.
1292   //===------------------------------------------------------------------===//
1293 
1294   ProgramStateRef assumeSymNE(ProgramStateRef State, SymbolRef Sym,
1295                               const llvm::APSInt &V,
1296                               const llvm::APSInt &Adjustment) override;
1297 
1298   ProgramStateRef assumeSymEQ(ProgramStateRef State, SymbolRef Sym,
1299                               const llvm::APSInt &V,
1300                               const llvm::APSInt &Adjustment) override;
1301 
1302   ProgramStateRef assumeSymLT(ProgramStateRef State, SymbolRef Sym,
1303                               const llvm::APSInt &V,
1304                               const llvm::APSInt &Adjustment) override;
1305 
1306   ProgramStateRef assumeSymGT(ProgramStateRef State, SymbolRef Sym,
1307                               const llvm::APSInt &V,
1308                               const llvm::APSInt &Adjustment) override;
1309 
1310   ProgramStateRef assumeSymLE(ProgramStateRef State, SymbolRef Sym,
1311                               const llvm::APSInt &V,
1312                               const llvm::APSInt &Adjustment) override;
1313 
1314   ProgramStateRef assumeSymGE(ProgramStateRef State, SymbolRef Sym,
1315                               const llvm::APSInt &V,
1316                               const llvm::APSInt &Adjustment) override;
1317 
1318   ProgramStateRef assumeSymWithinInclusiveRange(
1319       ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
1320       const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
1321 
1322   ProgramStateRef assumeSymOutsideInclusiveRange(
1323       ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
1324       const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
1325 
1326 private:
1327   RangeSet::Factory F;
1328 
1329   RangeSet getRange(ProgramStateRef State, SymbolRef Sym);
1330   RangeSet getRange(ProgramStateRef State, EquivalenceClass Class);
1331 
1332   RangeSet getSymLTRange(ProgramStateRef St, SymbolRef Sym,
1333                          const llvm::APSInt &Int,
1334                          const llvm::APSInt &Adjustment);
1335   RangeSet getSymGTRange(ProgramStateRef St, SymbolRef Sym,
1336                          const llvm::APSInt &Int,
1337                          const llvm::APSInt &Adjustment);
1338   RangeSet getSymLERange(ProgramStateRef St, SymbolRef Sym,
1339                          const llvm::APSInt &Int,
1340                          const llvm::APSInt &Adjustment);
1341   RangeSet getSymLERange(llvm::function_ref<RangeSet()> RS,
1342                          const llvm::APSInt &Int,
1343                          const llvm::APSInt &Adjustment);
1344   RangeSet getSymGERange(ProgramStateRef St, SymbolRef Sym,
1345                          const llvm::APSInt &Int,
1346                          const llvm::APSInt &Adjustment);
1347 
1348   //===------------------------------------------------------------------===//
1349   // Equality tracking implementation
1350   //===------------------------------------------------------------------===//
1351 
1352   ProgramStateRef trackEQ(RangeSet NewConstraint, ProgramStateRef State,
1353                           SymbolRef Sym, const llvm::APSInt &Int,
1354                           const llvm::APSInt &Adjustment) {
1355     return track<true>(NewConstraint, State, Sym, Int, Adjustment);
1356   }
1357 
1358   ProgramStateRef trackNE(RangeSet NewConstraint, ProgramStateRef State,
1359                           SymbolRef Sym, const llvm::APSInt &Int,
1360                           const llvm::APSInt &Adjustment) {
1361     return track<false>(NewConstraint, State, Sym, Int, Adjustment);
1362   }
1363 
1364   template <bool EQ>
1365   ProgramStateRef track(RangeSet NewConstraint, ProgramStateRef State,
1366                         SymbolRef Sym, const llvm::APSInt &Int,
1367                         const llvm::APSInt &Adjustment) {
1368     if (NewConstraint.isEmpty())
1369       // This is an infeasible assumption.
1370       return nullptr;
1371 
1372     ProgramStateRef NewState = setConstraint(State, Sym, NewConstraint);
1373     if (auto Equality = EqualityInfo::extract(Sym, Int, Adjustment)) {
1374       // If the original assumption is not Sym + Adjustment !=/</> Int,
1375       // we should invert IsEquality flag.
1376       Equality->IsEquality = Equality->IsEquality != EQ;
1377       return track(NewState, *Equality);
1378     }
1379 
1380     return NewState;
1381   }
1382 
1383   ProgramStateRef track(ProgramStateRef State, EqualityInfo ToTrack) {
1384     if (ToTrack.IsEquality) {
1385       return trackEquality(State, ToTrack.Left, ToTrack.Right);
1386     }
1387     return trackDisequality(State, ToTrack.Left, ToTrack.Right);
1388   }
1389 
1390   ProgramStateRef trackDisequality(ProgramStateRef State, SymbolRef LHS,
1391                                    SymbolRef RHS) {
1392     return EquivalenceClass::markDisequal(getBasicVals(), F, State, LHS, RHS);
1393   }
1394 
1395   ProgramStateRef trackEquality(ProgramStateRef State, SymbolRef LHS,
1396                                 SymbolRef RHS) {
1397     return EquivalenceClass::merge(getBasicVals(), F, State, LHS, RHS);
1398   }
1399 
1400   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
1401   areFeasible(ConstraintRangeTy Constraints) {
1402     return llvm::none_of(
1403         Constraints,
1404         [](const std::pair<EquivalenceClass, RangeSet> &ClassConstraint) {
1405           return ClassConstraint.second.isEmpty();
1406         });
1407   }
1408 
1409   LLVM_NODISCARD ProgramStateRef setConstraint(ProgramStateRef State,
1410                                                EquivalenceClass Class,
1411                                                RangeSet Constraint) {
1412     ConstraintRangeTy Constraints = State->get<ConstraintRange>();
1413     ConstraintRangeTy::Factory &CF = State->get_context<ConstraintRange>();
1414 
1415     assert(!Constraint.isEmpty() && "New constraint should not be empty");
1416 
1417     // Add new constraint.
1418     Constraints = CF.add(Constraints, Class, Constraint);
1419 
1420     // There is a chance that we might need to update constraints for the
1421     // classes that are known to be disequal to Class.
1422     //
1423     // In order for this to be even possible, the new constraint should
1424     // be simply a constant because we can't reason about range disequalities.
1425     if (const llvm::APSInt *Point = Constraint.getConcreteValue())
1426       for (EquivalenceClass DisequalClass : Class.getDisequalClasses(State)) {
1427         RangeSet UpdatedConstraint =
1428             getRange(State, DisequalClass).Delete(getBasicVals(), F, *Point);
1429 
1430         // If we end up with at least one of the disequal classes to be
1431         // constrainted with an empty range-set, the state is infeasible.
1432         if (UpdatedConstraint.isEmpty())
1433           return nullptr;
1434 
1435         Constraints = CF.add(Constraints, DisequalClass, UpdatedConstraint);
1436       }
1437 
1438     assert(areFeasible(Constraints) && "Constraint manager shouldn't produce "
1439                                        "a state with infeasible constraints");
1440 
1441     return State->set<ConstraintRange>(Constraints);
1442   }
1443 
1444   LLVM_NODISCARD inline ProgramStateRef
1445   setConstraint(ProgramStateRef State, SymbolRef Sym, RangeSet Constraint) {
1446     return setConstraint(State, EquivalenceClass::find(State, Sym), Constraint);
1447   }
1448 };
1449 
1450 } // end anonymous namespace
1451 
1452 std::unique_ptr<ConstraintManager>
1453 ento::CreateRangeConstraintManager(ProgramStateManager &StMgr,
1454                                    ExprEngine *Eng) {
1455   return std::make_unique<RangeConstraintManager>(Eng, StMgr.getSValBuilder());
1456 }
1457 
1458 ConstraintMap ento::getConstraintMap(ProgramStateRef State) {
1459   ConstraintMap::Factory &F = State->get_context<ConstraintMap>();
1460   ConstraintMap Result = F.getEmptyMap();
1461 
1462   ConstraintRangeTy Constraints = State->get<ConstraintRange>();
1463   for (std::pair<EquivalenceClass, RangeSet> ClassConstraint : Constraints) {
1464     EquivalenceClass Class = ClassConstraint.first;
1465     SymbolSet ClassMembers = Class.getClassMembers(State);
1466     assert(!ClassMembers.isEmpty() &&
1467            "Class must always have at least one member!");
1468 
1469     SymbolRef Representative = *ClassMembers.begin();
1470     Result = F.add(Result, Representative, ClassConstraint.second);
1471   }
1472 
1473   return Result;
1474 }
1475 
1476 //===----------------------------------------------------------------------===//
1477 //                     EqualityClass implementation details
1478 //===----------------------------------------------------------------------===//
1479 
1480 inline EquivalenceClass EquivalenceClass::find(ProgramStateRef State,
1481                                                SymbolRef Sym) {
1482   // We store far from all Symbol -> Class mappings
1483   if (const EquivalenceClass *NontrivialClass = State->get<ClassMap>(Sym))
1484     return *NontrivialClass;
1485 
1486   // This is a trivial class of Sym.
1487   return Sym;
1488 }
1489 
1490 inline ProgramStateRef EquivalenceClass::merge(BasicValueFactory &BV,
1491                                                RangeSet::Factory &F,
1492                                                ProgramStateRef State,
1493                                                SymbolRef First,
1494                                                SymbolRef Second) {
1495   EquivalenceClass FirstClass = find(State, First);
1496   EquivalenceClass SecondClass = find(State, Second);
1497 
1498   return FirstClass.merge(BV, F, State, SecondClass);
1499 }
1500 
1501 inline ProgramStateRef EquivalenceClass::merge(BasicValueFactory &BV,
1502                                                RangeSet::Factory &F,
1503                                                ProgramStateRef State,
1504                                                EquivalenceClass Other) {
1505   // It is already the same class.
1506   if (*this == Other)
1507     return State;
1508 
1509   // FIXME: As of now, we support only equivalence classes of the same type.
1510   //        This limitation is connected to the lack of explicit casts in
1511   //        our symbolic expression model.
1512   //
1513   //        That means that for `int x` and `char y` we don't distinguish
1514   //        between these two very different cases:
1515   //          * `x == y`
1516   //          * `(char)x == y`
1517   //
1518   //        The moment we introduce symbolic casts, this restriction can be
1519   //        lifted.
1520   if (getType() != Other.getType())
1521     return State;
1522 
1523   SymbolSet Members = getClassMembers(State);
1524   SymbolSet OtherMembers = Other.getClassMembers(State);
1525 
1526   // We estimate the size of the class by the height of tree containing
1527   // its members.  Merging is not a trivial operation, so it's easier to
1528   // merge the smaller class into the bigger one.
1529   if (Members.getHeight() >= OtherMembers.getHeight()) {
1530     return mergeImpl(BV, F, State, Members, Other, OtherMembers);
1531   } else {
1532     return Other.mergeImpl(BV, F, State, OtherMembers, *this, Members);
1533   }
1534 }
1535 
1536 inline ProgramStateRef
1537 EquivalenceClass::mergeImpl(BasicValueFactory &ValueFactory,
1538                             RangeSet::Factory &RangeFactory,
1539                             ProgramStateRef State, SymbolSet MyMembers,
1540                             EquivalenceClass Other, SymbolSet OtherMembers) {
1541   // Essentially what we try to recreate here is some kind of union-find
1542   // data structure.  It does have certain limitations due to persistence
1543   // and the need to remove elements from classes.
1544   //
1545   // In this setting, EquialityClass object is the representative of the class
1546   // or the parent element.  ClassMap is a mapping of class members to their
1547   // parent. Unlike the union-find structure, they all point directly to the
1548   // class representative because we don't have an opportunity to actually do
1549   // path compression when dealing with immutability.  This means that we
1550   // compress paths every time we do merges.  It also means that we lose
1551   // the main amortized complexity benefit from the original data structure.
1552   ConstraintRangeTy Constraints = State->get<ConstraintRange>();
1553   ConstraintRangeTy::Factory &CRF = State->get_context<ConstraintRange>();
1554 
1555   // 1. If the merged classes have any constraints associated with them, we
1556   //    need to transfer them to the class we have left.
1557   //
1558   // Intersection here makes perfect sense because both of these constraints
1559   // must hold for the whole new class.
1560   if (Optional<RangeSet> NewClassConstraint =
1561           intersect(ValueFactory, RangeFactory, getConstraint(State, *this),
1562                     getConstraint(State, Other))) {
1563     // NOTE: Essentially, NewClassConstraint should NEVER be infeasible because
1564     //       range inferrer shouldn't generate ranges incompatible with
1565     //       equivalence classes. However, at the moment, due to imperfections
1566     //       in the solver, it is possible and the merge function can also
1567     //       return infeasible states aka null states.
1568     if (NewClassConstraint->isEmpty())
1569       // Infeasible state
1570       return nullptr;
1571 
1572     // No need in tracking constraints of a now-dissolved class.
1573     Constraints = CRF.remove(Constraints, Other);
1574     // Assign new constraints for this class.
1575     Constraints = CRF.add(Constraints, *this, *NewClassConstraint);
1576 
1577     State = State->set<ConstraintRange>(Constraints);
1578   }
1579 
1580   // 2. Get ALL equivalence-related maps
1581   ClassMapTy Classes = State->get<ClassMap>();
1582   ClassMapTy::Factory &CMF = State->get_context<ClassMap>();
1583 
1584   ClassMembersTy Members = State->get<ClassMembers>();
1585   ClassMembersTy::Factory &MF = State->get_context<ClassMembers>();
1586 
1587   DisequalityMapTy DisequalityInfo = State->get<DisequalityMap>();
1588   DisequalityMapTy::Factory &DF = State->get_context<DisequalityMap>();
1589 
1590   ClassSet::Factory &CF = State->get_context<ClassSet>();
1591   SymbolSet::Factory &F = getMembersFactory(State);
1592 
1593   // 2. Merge members of the Other class into the current class.
1594   SymbolSet NewClassMembers = MyMembers;
1595   for (SymbolRef Sym : OtherMembers) {
1596     NewClassMembers = F.add(NewClassMembers, Sym);
1597     // *this is now the class for all these new symbols.
1598     Classes = CMF.add(Classes, Sym, *this);
1599   }
1600 
1601   // 3. Adjust member mapping.
1602   //
1603   // No need in tracking members of a now-dissolved class.
1604   Members = MF.remove(Members, Other);
1605   // Now only the current class is mapped to all the symbols.
1606   Members = MF.add(Members, *this, NewClassMembers);
1607 
1608   // 4. Update disequality relations
1609   ClassSet DisequalToOther = Other.getDisequalClasses(DisequalityInfo, CF);
1610   if (!DisequalToOther.isEmpty()) {
1611     ClassSet DisequalToThis = getDisequalClasses(DisequalityInfo, CF);
1612     DisequalityInfo = DF.remove(DisequalityInfo, Other);
1613 
1614     for (EquivalenceClass DisequalClass : DisequalToOther) {
1615       DisequalToThis = CF.add(DisequalToThis, DisequalClass);
1616 
1617       // Disequality is a symmetric relation meaning that if
1618       // DisequalToOther not null then the set for DisequalClass is not
1619       // empty and has at least Other.
1620       ClassSet OriginalSetLinkedToOther =
1621           *DisequalityInfo.lookup(DisequalClass);
1622 
1623       // Other will be eliminated and we should replace it with the bigger
1624       // united class.
1625       ClassSet NewSet = CF.remove(OriginalSetLinkedToOther, Other);
1626       NewSet = CF.add(NewSet, *this);
1627 
1628       DisequalityInfo = DF.add(DisequalityInfo, DisequalClass, NewSet);
1629     }
1630 
1631     DisequalityInfo = DF.add(DisequalityInfo, *this, DisequalToThis);
1632     State = State->set<DisequalityMap>(DisequalityInfo);
1633   }
1634 
1635   // 5. Update the state
1636   State = State->set<ClassMap>(Classes);
1637   State = State->set<ClassMembers>(Members);
1638 
1639   return State;
1640 }
1641 
1642 inline SymbolSet::Factory &
1643 EquivalenceClass::getMembersFactory(ProgramStateRef State) {
1644   return State->get_context<SymbolSet>();
1645 }
1646 
1647 SymbolSet EquivalenceClass::getClassMembers(ProgramStateRef State) {
1648   if (const SymbolSet *Members = State->get<ClassMembers>(*this))
1649     return *Members;
1650 
1651   // This class is trivial, so we need to construct a set
1652   // with just that one symbol from the class.
1653   SymbolSet::Factory &F = getMembersFactory(State);
1654   return F.add(F.getEmptySet(), getRepresentativeSymbol());
1655 }
1656 
1657 bool EquivalenceClass::isTrivial(ProgramStateRef State) {
1658   return State->get<ClassMembers>(*this) == nullptr;
1659 }
1660 
1661 bool EquivalenceClass::isTriviallyDead(ProgramStateRef State,
1662                                        SymbolReaper &Reaper) {
1663   return isTrivial(State) && Reaper.isDead(getRepresentativeSymbol());
1664 }
1665 
1666 inline ProgramStateRef EquivalenceClass::markDisequal(BasicValueFactory &VF,
1667                                                       RangeSet::Factory &RF,
1668                                                       ProgramStateRef State,
1669                                                       SymbolRef First,
1670                                                       SymbolRef Second) {
1671   return markDisequal(VF, RF, State, find(State, First), find(State, Second));
1672 }
1673 
1674 inline ProgramStateRef EquivalenceClass::markDisequal(BasicValueFactory &VF,
1675                                                       RangeSet::Factory &RF,
1676                                                       ProgramStateRef State,
1677                                                       EquivalenceClass First,
1678                                                       EquivalenceClass Second) {
1679   return First.markDisequal(VF, RF, State, Second);
1680 }
1681 
1682 inline ProgramStateRef
1683 EquivalenceClass::markDisequal(BasicValueFactory &VF, RangeSet::Factory &RF,
1684                                ProgramStateRef State,
1685                                EquivalenceClass Other) const {
1686   // If we know that two classes are equal, we can only produce an infeasible
1687   // state.
1688   if (*this == Other) {
1689     return nullptr;
1690   }
1691 
1692   DisequalityMapTy DisequalityInfo = State->get<DisequalityMap>();
1693   ConstraintRangeTy Constraints = State->get<ConstraintRange>();
1694 
1695   // Disequality is a symmetric relation, so if we mark A as disequal to B,
1696   // we should also mark B as disequalt to A.
1697   addToDisequalityInfo(DisequalityInfo, Constraints, VF, RF, State, *this,
1698                        Other);
1699   addToDisequalityInfo(DisequalityInfo, Constraints, VF, RF, State, Other,
1700                        *this);
1701 
1702   State = State->set<DisequalityMap>(DisequalityInfo);
1703   State = State->set<ConstraintRange>(Constraints);
1704 
1705   return State;
1706 }
1707 
1708 inline void EquivalenceClass::addToDisequalityInfo(
1709     DisequalityMapTy &Info, ConstraintRangeTy &Constraints,
1710     BasicValueFactory &VF, RangeSet::Factory &RF, ProgramStateRef State,
1711     EquivalenceClass First, EquivalenceClass Second) {
1712 
1713   // 1. Get all of the required factories.
1714   DisequalityMapTy::Factory &F = State->get_context<DisequalityMap>();
1715   ClassSet::Factory &CF = State->get_context<ClassSet>();
1716   ConstraintRangeTy::Factory &CRF = State->get_context<ConstraintRange>();
1717 
1718   // 2. Add Second to the set of classes disequal to First.
1719   const ClassSet *CurrentSet = Info.lookup(First);
1720   ClassSet NewSet = CurrentSet ? *CurrentSet : CF.getEmptySet();
1721   NewSet = CF.add(NewSet, Second);
1722 
1723   Info = F.add(Info, First, NewSet);
1724 
1725   // 3. If Second is known to be a constant, we can delete this point
1726   //    from the constraint asociated with First.
1727   //
1728   //    So, if Second == 10, it means that First != 10.
1729   //    At the same time, the same logic does not apply to ranges.
1730   if (const RangeSet *SecondConstraint = Constraints.lookup(Second))
1731     if (const llvm::APSInt *Point = SecondConstraint->getConcreteValue()) {
1732 
1733       RangeSet FirstConstraint = SymbolicRangeInferrer::inferRange(
1734           VF, RF, State, First.getRepresentativeSymbol());
1735 
1736       FirstConstraint = FirstConstraint.Delete(VF, RF, *Point);
1737       Constraints = CRF.add(Constraints, First, FirstConstraint);
1738     }
1739 }
1740 
1741 inline Optional<bool> EquivalenceClass::areEqual(ProgramStateRef State,
1742                                                  SymbolRef FirstSym,
1743                                                  SymbolRef SecondSym) {
1744   EquivalenceClass First = find(State, FirstSym);
1745   EquivalenceClass Second = find(State, SecondSym);
1746 
1747   // The same equivalence class => symbols are equal.
1748   if (First == Second)
1749     return true;
1750 
1751   // Let's check if we know anything about these two classes being not equal to
1752   // each other.
1753   ClassSet DisequalToFirst = First.getDisequalClasses(State);
1754   if (DisequalToFirst.contains(Second))
1755     return false;
1756 
1757   // It is not clear.
1758   return llvm::None;
1759 }
1760 
1761 inline ClassSet EquivalenceClass::getDisequalClasses(ProgramStateRef State,
1762                                                      SymbolRef Sym) {
1763   return find(State, Sym).getDisequalClasses(State);
1764 }
1765 
1766 inline ClassSet
1767 EquivalenceClass::getDisequalClasses(ProgramStateRef State) const {
1768   return getDisequalClasses(State->get<DisequalityMap>(),
1769                             State->get_context<ClassSet>());
1770 }
1771 
1772 inline ClassSet
1773 EquivalenceClass::getDisequalClasses(DisequalityMapTy Map,
1774                                      ClassSet::Factory &Factory) const {
1775   if (const ClassSet *DisequalClasses = Map.lookup(*this))
1776     return *DisequalClasses;
1777 
1778   return Factory.getEmptySet();
1779 }
1780 
1781 bool EquivalenceClass::isClassDataConsistent(ProgramStateRef State) {
1782   ClassMembersTy Members = State->get<ClassMembers>();
1783 
1784   for (std::pair<EquivalenceClass, SymbolSet> ClassMembersPair : Members) {
1785     for (SymbolRef Member : ClassMembersPair.second) {
1786       // Every member of the class should have a mapping back to the class.
1787       if (find(State, Member) == ClassMembersPair.first) {
1788         continue;
1789       }
1790 
1791       return false;
1792     }
1793   }
1794 
1795   DisequalityMapTy Disequalities = State->get<DisequalityMap>();
1796   for (std::pair<EquivalenceClass, ClassSet> DisequalityInfo : Disequalities) {
1797     EquivalenceClass Class = DisequalityInfo.first;
1798     ClassSet DisequalClasses = DisequalityInfo.second;
1799 
1800     // There is no use in keeping empty sets in the map.
1801     if (DisequalClasses.isEmpty())
1802       return false;
1803 
1804     // Disequality is symmetrical, i.e. for every Class A and B that A != B,
1805     // B != A should also be true.
1806     for (EquivalenceClass DisequalClass : DisequalClasses) {
1807       const ClassSet *DisequalToDisequalClasses =
1808           Disequalities.lookup(DisequalClass);
1809 
1810       // It should be a set of at least one element: Class
1811       if (!DisequalToDisequalClasses ||
1812           !DisequalToDisequalClasses->contains(Class))
1813         return false;
1814     }
1815   }
1816 
1817   return true;
1818 }
1819 
1820 //===----------------------------------------------------------------------===//
1821 //                    RangeConstraintManager implementation
1822 //===----------------------------------------------------------------------===//
1823 
1824 bool RangeConstraintManager::canReasonAbout(SVal X) const {
1825   Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
1826   if (SymVal && SymVal->isExpression()) {
1827     const SymExpr *SE = SymVal->getSymbol();
1828 
1829     if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
1830       switch (SIE->getOpcode()) {
1831       // We don't reason yet about bitwise-constraints on symbolic values.
1832       case BO_And:
1833       case BO_Or:
1834       case BO_Xor:
1835         return false;
1836       // We don't reason yet about these arithmetic constraints on
1837       // symbolic values.
1838       case BO_Mul:
1839       case BO_Div:
1840       case BO_Rem:
1841       case BO_Shl:
1842       case BO_Shr:
1843         return false;
1844       // All other cases.
1845       default:
1846         return true;
1847       }
1848     }
1849 
1850     if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
1851       // FIXME: Handle <=> here.
1852       if (BinaryOperator::isEqualityOp(SSE->getOpcode()) ||
1853           BinaryOperator::isRelationalOp(SSE->getOpcode())) {
1854         // We handle Loc <> Loc comparisons, but not (yet) NonLoc <> NonLoc.
1855         // We've recently started producing Loc <> NonLoc comparisons (that
1856         // result from casts of one of the operands between eg. intptr_t and
1857         // void *), but we can't reason about them yet.
1858         if (Loc::isLocType(SSE->getLHS()->getType())) {
1859           return Loc::isLocType(SSE->getRHS()->getType());
1860         }
1861       }
1862     }
1863 
1864     return false;
1865   }
1866 
1867   return true;
1868 }
1869 
1870 ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
1871                                                     SymbolRef Sym) {
1872   const RangeSet *Ranges = getConstraint(State, Sym);
1873 
1874   // If we don't have any information about this symbol, it's underconstrained.
1875   if (!Ranges)
1876     return ConditionTruthVal();
1877 
1878   // If we have a concrete value, see if it's zero.
1879   if (const llvm::APSInt *Value = Ranges->getConcreteValue())
1880     return *Value == 0;
1881 
1882   BasicValueFactory &BV = getBasicVals();
1883   APSIntType IntType = BV.getAPSIntType(Sym->getType());
1884   llvm::APSInt Zero = IntType.getZeroValue();
1885 
1886   // Check if zero is in the set of possible values.
1887   if (Ranges->Intersect(BV, F, Zero, Zero).isEmpty())
1888     return false;
1889 
1890   // Zero is a possible value, but it is not the /only/ possible value.
1891   return ConditionTruthVal();
1892 }
1893 
1894 const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
1895                                                       SymbolRef Sym) const {
1896   const RangeSet *T = getConstraint(St, Sym);
1897   return T ? T->getConcreteValue() : nullptr;
1898 }
1899 
1900 //===----------------------------------------------------------------------===//
1901 //                Remove dead symbols from existing constraints
1902 //===----------------------------------------------------------------------===//
1903 
1904 /// Scan all symbols referenced by the constraints. If the symbol is not alive
1905 /// as marked in LSymbols, mark it as dead in DSymbols.
1906 ProgramStateRef
1907 RangeConstraintManager::removeDeadBindings(ProgramStateRef State,
1908                                            SymbolReaper &SymReaper) {
1909   ClassMembersTy ClassMembersMap = State->get<ClassMembers>();
1910   ClassMembersTy NewClassMembersMap = ClassMembersMap;
1911   ClassMembersTy::Factory &EMFactory = State->get_context<ClassMembers>();
1912   SymbolSet::Factory &SetFactory = State->get_context<SymbolSet>();
1913 
1914   ConstraintRangeTy Constraints = State->get<ConstraintRange>();
1915   ConstraintRangeTy NewConstraints = Constraints;
1916   ConstraintRangeTy::Factory &ConstraintFactory =
1917       State->get_context<ConstraintRange>();
1918 
1919   ClassMapTy Map = State->get<ClassMap>();
1920   ClassMapTy NewMap = Map;
1921   ClassMapTy::Factory &ClassFactory = State->get_context<ClassMap>();
1922 
1923   DisequalityMapTy Disequalities = State->get<DisequalityMap>();
1924   DisequalityMapTy::Factory &DisequalityFactory =
1925       State->get_context<DisequalityMap>();
1926   ClassSet::Factory &ClassSetFactory = State->get_context<ClassSet>();
1927 
1928   bool ClassMapChanged = false;
1929   bool MembersMapChanged = false;
1930   bool ConstraintMapChanged = false;
1931   bool DisequalitiesChanged = false;
1932 
1933   auto removeDeadClass = [&](EquivalenceClass Class) {
1934     // Remove associated constraint ranges.
1935     Constraints = ConstraintFactory.remove(Constraints, Class);
1936     ConstraintMapChanged = true;
1937 
1938     // Update disequality information to not hold any information on the
1939     // removed class.
1940     ClassSet DisequalClasses =
1941         Class.getDisequalClasses(Disequalities, ClassSetFactory);
1942     if (!DisequalClasses.isEmpty()) {
1943       for (EquivalenceClass DisequalClass : DisequalClasses) {
1944         ClassSet DisequalToDisequalSet =
1945             DisequalClass.getDisequalClasses(Disequalities, ClassSetFactory);
1946         // DisequalToDisequalSet is guaranteed to be non-empty for consistent
1947         // disequality info.
1948         assert(!DisequalToDisequalSet.isEmpty());
1949         ClassSet NewSet = ClassSetFactory.remove(DisequalToDisequalSet, Class);
1950 
1951         // No need in keeping an empty set.
1952         if (NewSet.isEmpty()) {
1953           Disequalities =
1954               DisequalityFactory.remove(Disequalities, DisequalClass);
1955         } else {
1956           Disequalities =
1957               DisequalityFactory.add(Disequalities, DisequalClass, NewSet);
1958         }
1959       }
1960       // Remove the data for the class
1961       Disequalities = DisequalityFactory.remove(Disequalities, Class);
1962       DisequalitiesChanged = true;
1963     }
1964   };
1965 
1966   // 1. Let's see if dead symbols are trivial and have associated constraints.
1967   for (std::pair<EquivalenceClass, RangeSet> ClassConstraintPair :
1968        Constraints) {
1969     EquivalenceClass Class = ClassConstraintPair.first;
1970     if (Class.isTriviallyDead(State, SymReaper)) {
1971       // If this class is trivial, we can remove its constraints right away.
1972       removeDeadClass(Class);
1973     }
1974   }
1975 
1976   // 2. We don't need to track classes for dead symbols.
1977   for (std::pair<SymbolRef, EquivalenceClass> SymbolClassPair : Map) {
1978     SymbolRef Sym = SymbolClassPair.first;
1979 
1980     if (SymReaper.isDead(Sym)) {
1981       ClassMapChanged = true;
1982       NewMap = ClassFactory.remove(NewMap, Sym);
1983     }
1984   }
1985 
1986   // 3. Remove dead members from classes and remove dead non-trivial classes
1987   //    and their constraints.
1988   for (std::pair<EquivalenceClass, SymbolSet> ClassMembersPair :
1989        ClassMembersMap) {
1990     EquivalenceClass Class = ClassMembersPair.first;
1991     SymbolSet LiveMembers = ClassMembersPair.second;
1992     bool MembersChanged = false;
1993 
1994     for (SymbolRef Member : ClassMembersPair.second) {
1995       if (SymReaper.isDead(Member)) {
1996         MembersChanged = true;
1997         LiveMembers = SetFactory.remove(LiveMembers, Member);
1998       }
1999     }
2000 
2001     // Check if the class changed.
2002     if (!MembersChanged)
2003       continue;
2004 
2005     MembersMapChanged = true;
2006 
2007     if (LiveMembers.isEmpty()) {
2008       // The class is dead now, we need to wipe it out of the members map...
2009       NewClassMembersMap = EMFactory.remove(NewClassMembersMap, Class);
2010 
2011       // ...and remove all of its constraints.
2012       removeDeadClass(Class);
2013     } else {
2014       // We need to change the members associated with the class.
2015       NewClassMembersMap =
2016           EMFactory.add(NewClassMembersMap, Class, LiveMembers);
2017     }
2018   }
2019 
2020   // 4. Update the state with new maps.
2021   //
2022   // Here we try to be humble and update a map only if it really changed.
2023   if (ClassMapChanged)
2024     State = State->set<ClassMap>(NewMap);
2025 
2026   if (MembersMapChanged)
2027     State = State->set<ClassMembers>(NewClassMembersMap);
2028 
2029   if (ConstraintMapChanged)
2030     State = State->set<ConstraintRange>(Constraints);
2031 
2032   if (DisequalitiesChanged)
2033     State = State->set<DisequalityMap>(Disequalities);
2034 
2035   assert(EquivalenceClass::isClassDataConsistent(State));
2036 
2037   return State;
2038 }
2039 
2040 RangeSet RangeConstraintManager::getRange(ProgramStateRef State,
2041                                           SymbolRef Sym) {
2042   return SymbolicRangeInferrer::inferRange(getBasicVals(), F, State, Sym);
2043 }
2044 
2045 RangeSet RangeConstraintManager::getRange(ProgramStateRef State,
2046                                           EquivalenceClass Class) {
2047   return SymbolicRangeInferrer::inferRange(getBasicVals(), F, State, Class);
2048 }
2049 
2050 //===------------------------------------------------------------------------===
2051 // assumeSymX methods: protected interface for RangeConstraintManager.
2052 //===------------------------------------------------------------------------===/
2053 
2054 // The syntax for ranges below is mathematical, using [x, y] for closed ranges
2055 // and (x, y) for open ranges. These ranges are modular, corresponding with
2056 // a common treatment of C integer overflow. This means that these methods
2057 // do not have to worry about overflow; RangeSet::Intersect can handle such a
2058 // "wraparound" range.
2059 // As an example, the range [UINT_MAX-1, 3) contains five values: UINT_MAX-1,
2060 // UINT_MAX, 0, 1, and 2.
2061 
2062 ProgramStateRef
2063 RangeConstraintManager::assumeSymNE(ProgramStateRef St, SymbolRef Sym,
2064                                     const llvm::APSInt &Int,
2065                                     const llvm::APSInt &Adjustment) {
2066   // Before we do any real work, see if the value can even show up.
2067   APSIntType AdjustmentType(Adjustment);
2068   if (AdjustmentType.testInRange(Int, true) != APSIntType::RTR_Within)
2069     return St;
2070 
2071   llvm::APSInt Point = AdjustmentType.convert(Int) - Adjustment;
2072 
2073   RangeSet New = getRange(St, Sym).Delete(getBasicVals(), F, Point);
2074 
2075   return trackNE(New, St, Sym, Int, Adjustment);
2076 }
2077 
2078 ProgramStateRef
2079 RangeConstraintManager::assumeSymEQ(ProgramStateRef St, SymbolRef Sym,
2080                                     const llvm::APSInt &Int,
2081                                     const llvm::APSInt &Adjustment) {
2082   // Before we do any real work, see if the value can even show up.
2083   APSIntType AdjustmentType(Adjustment);
2084   if (AdjustmentType.testInRange(Int, true) != APSIntType::RTR_Within)
2085     return nullptr;
2086 
2087   // [Int-Adjustment, Int-Adjustment]
2088   llvm::APSInt AdjInt = AdjustmentType.convert(Int) - Adjustment;
2089   RangeSet New = getRange(St, Sym).Intersect(getBasicVals(), F, AdjInt, AdjInt);
2090 
2091   return trackEQ(New, St, Sym, Int, Adjustment);
2092 }
2093 
2094 RangeSet RangeConstraintManager::getSymLTRange(ProgramStateRef St,
2095                                                SymbolRef Sym,
2096                                                const llvm::APSInt &Int,
2097                                                const llvm::APSInt &Adjustment) {
2098   // Before we do any real work, see if the value can even show up.
2099   APSIntType AdjustmentType(Adjustment);
2100   switch (AdjustmentType.testInRange(Int, true)) {
2101   case APSIntType::RTR_Below:
2102     return F.getEmptySet();
2103   case APSIntType::RTR_Within:
2104     break;
2105   case APSIntType::RTR_Above:
2106     return getRange(St, Sym);
2107   }
2108 
2109   // Special case for Int == Min. This is always false.
2110   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
2111   llvm::APSInt Min = AdjustmentType.getMinValue();
2112   if (ComparisonVal == Min)
2113     return F.getEmptySet();
2114 
2115   llvm::APSInt Lower = Min - Adjustment;
2116   llvm::APSInt Upper = ComparisonVal - Adjustment;
2117   --Upper;
2118 
2119   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
2120 }
2121 
2122 ProgramStateRef
2123 RangeConstraintManager::assumeSymLT(ProgramStateRef St, SymbolRef Sym,
2124                                     const llvm::APSInt &Int,
2125                                     const llvm::APSInt &Adjustment) {
2126   RangeSet New = getSymLTRange(St, Sym, Int, Adjustment);
2127   return trackNE(New, St, Sym, Int, Adjustment);
2128 }
2129 
2130 RangeSet RangeConstraintManager::getSymGTRange(ProgramStateRef St,
2131                                                SymbolRef Sym,
2132                                                const llvm::APSInt &Int,
2133                                                const llvm::APSInt &Adjustment) {
2134   // Before we do any real work, see if the value can even show up.
2135   APSIntType AdjustmentType(Adjustment);
2136   switch (AdjustmentType.testInRange(Int, true)) {
2137   case APSIntType::RTR_Below:
2138     return getRange(St, Sym);
2139   case APSIntType::RTR_Within:
2140     break;
2141   case APSIntType::RTR_Above:
2142     return F.getEmptySet();
2143   }
2144 
2145   // Special case for Int == Max. This is always false.
2146   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
2147   llvm::APSInt Max = AdjustmentType.getMaxValue();
2148   if (ComparisonVal == Max)
2149     return F.getEmptySet();
2150 
2151   llvm::APSInt Lower = ComparisonVal - Adjustment;
2152   llvm::APSInt Upper = Max - Adjustment;
2153   ++Lower;
2154 
2155   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
2156 }
2157 
2158 ProgramStateRef
2159 RangeConstraintManager::assumeSymGT(ProgramStateRef St, SymbolRef Sym,
2160                                     const llvm::APSInt &Int,
2161                                     const llvm::APSInt &Adjustment) {
2162   RangeSet New = getSymGTRange(St, Sym, Int, Adjustment);
2163   return trackNE(New, St, Sym, Int, Adjustment);
2164 }
2165 
2166 RangeSet RangeConstraintManager::getSymGERange(ProgramStateRef St,
2167                                                SymbolRef Sym,
2168                                                const llvm::APSInt &Int,
2169                                                const llvm::APSInt &Adjustment) {
2170   // Before we do any real work, see if the value can even show up.
2171   APSIntType AdjustmentType(Adjustment);
2172   switch (AdjustmentType.testInRange(Int, true)) {
2173   case APSIntType::RTR_Below:
2174     return getRange(St, Sym);
2175   case APSIntType::RTR_Within:
2176     break;
2177   case APSIntType::RTR_Above:
2178     return F.getEmptySet();
2179   }
2180 
2181   // Special case for Int == Min. This is always feasible.
2182   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
2183   llvm::APSInt Min = AdjustmentType.getMinValue();
2184   if (ComparisonVal == Min)
2185     return getRange(St, Sym);
2186 
2187   llvm::APSInt Max = AdjustmentType.getMaxValue();
2188   llvm::APSInt Lower = ComparisonVal - Adjustment;
2189   llvm::APSInt Upper = Max - Adjustment;
2190 
2191   return getRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
2192 }
2193 
2194 ProgramStateRef
2195 RangeConstraintManager::assumeSymGE(ProgramStateRef St, SymbolRef Sym,
2196                                     const llvm::APSInt &Int,
2197                                     const llvm::APSInt &Adjustment) {
2198   RangeSet New = getSymGERange(St, Sym, Int, Adjustment);
2199   return New.isEmpty() ? nullptr : setConstraint(St, Sym, New);
2200 }
2201 
2202 RangeSet
2203 RangeConstraintManager::getSymLERange(llvm::function_ref<RangeSet()> RS,
2204                                       const llvm::APSInt &Int,
2205                                       const llvm::APSInt &Adjustment) {
2206   // Before we do any real work, see if the value can even show up.
2207   APSIntType AdjustmentType(Adjustment);
2208   switch (AdjustmentType.testInRange(Int, true)) {
2209   case APSIntType::RTR_Below:
2210     return F.getEmptySet();
2211   case APSIntType::RTR_Within:
2212     break;
2213   case APSIntType::RTR_Above:
2214     return RS();
2215   }
2216 
2217   // Special case for Int == Max. This is always feasible.
2218   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
2219   llvm::APSInt Max = AdjustmentType.getMaxValue();
2220   if (ComparisonVal == Max)
2221     return RS();
2222 
2223   llvm::APSInt Min = AdjustmentType.getMinValue();
2224   llvm::APSInt Lower = Min - Adjustment;
2225   llvm::APSInt Upper = ComparisonVal - Adjustment;
2226 
2227   return RS().Intersect(getBasicVals(), F, Lower, Upper);
2228 }
2229 
2230 RangeSet RangeConstraintManager::getSymLERange(ProgramStateRef St,
2231                                                SymbolRef Sym,
2232                                                const llvm::APSInt &Int,
2233                                                const llvm::APSInt &Adjustment) {
2234   return getSymLERange([&] { return getRange(St, Sym); }, Int, Adjustment);
2235 }
2236 
2237 ProgramStateRef
2238 RangeConstraintManager::assumeSymLE(ProgramStateRef St, SymbolRef Sym,
2239                                     const llvm::APSInt &Int,
2240                                     const llvm::APSInt &Adjustment) {
2241   RangeSet New = getSymLERange(St, Sym, Int, Adjustment);
2242   return New.isEmpty() ? nullptr : setConstraint(St, Sym, New);
2243 }
2244 
2245 ProgramStateRef RangeConstraintManager::assumeSymWithinInclusiveRange(
2246     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
2247     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
2248   RangeSet New = getSymGERange(State, Sym, From, Adjustment);
2249   if (New.isEmpty())
2250     return nullptr;
2251   RangeSet Out = getSymLERange([&] { return New; }, To, Adjustment);
2252   return Out.isEmpty() ? nullptr : setConstraint(State, Sym, Out);
2253 }
2254 
2255 ProgramStateRef RangeConstraintManager::assumeSymOutsideInclusiveRange(
2256     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
2257     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
2258   RangeSet RangeLT = getSymLTRange(State, Sym, From, Adjustment);
2259   RangeSet RangeGT = getSymGTRange(State, Sym, To, Adjustment);
2260   RangeSet New(RangeLT.addRange(F, RangeGT));
2261   return New.isEmpty() ? nullptr : setConstraint(State, Sym, New);
2262 }
2263 
2264 //===----------------------------------------------------------------------===//
2265 // Pretty-printing.
2266 //===----------------------------------------------------------------------===//
2267 
2268 void RangeConstraintManager::printJson(raw_ostream &Out, ProgramStateRef State,
2269                                        const char *NL, unsigned int Space,
2270                                        bool IsDot) const {
2271   ConstraintRangeTy Constraints = State->get<ConstraintRange>();
2272 
2273   Indent(Out, Space, IsDot) << "\"constraints\": ";
2274   if (Constraints.isEmpty()) {
2275     Out << "null," << NL;
2276     return;
2277   }
2278 
2279   ++Space;
2280   Out << '[' << NL;
2281   bool First = true;
2282   for (std::pair<EquivalenceClass, RangeSet> P : Constraints) {
2283     SymbolSet ClassMembers = P.first.getClassMembers(State);
2284 
2285     // We can print the same constraint for every class member.
2286     for (SymbolRef ClassMember : ClassMembers) {
2287       if (First) {
2288         First = false;
2289       } else {
2290         Out << ',';
2291         Out << NL;
2292       }
2293       Indent(Out, Space, IsDot)
2294           << "{ \"symbol\": \"" << ClassMember << "\", \"range\": \"";
2295       P.second.print(Out);
2296       Out << "\" }";
2297     }
2298   }
2299   Out << NL;
2300 
2301   --Space;
2302   Indent(Out, Space, IsDot) << "]," << NL;
2303 }
2304