RangeConstraintManager.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. //== RangeConstraintManager.cpp - Manage range constraints.------*- C++ -*--==//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines RangeConstraintManager, a class that tracks simple
  11. // equality and inequality constraints on symbolic values of ProgramState.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "SimpleConstraintManager.h"
  15. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
  16. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
  17. #include "llvm/Support/Debug.h"
  18. #include "llvm/ADT/FoldingSet.h"
  19. #include "llvm/ADT/ImmutableSet.h"
  20. #include "llvm/Support/raw_ostream.h"
  21. using namespace clang;
  22. using namespace ento;
  23. namespace { class ConstraintRange {}; }
  24. static int ConstraintRangeIndex = 0;
  25. /// A Range represents the closed range [from, to]. The caller must
  26. /// guarantee that from <= to. Note that Range is immutable, so as not
  27. /// to subvert RangeSet's immutability.
  28. namespace {
  29. class Range : public std::pair<const llvm::APSInt*,
  30. const llvm::APSInt*> {
  31. public:
  32. Range(const llvm::APSInt &from, const llvm::APSInt &to)
  33. : std::pair<const llvm::APSInt*, const llvm::APSInt*>(&from, &to) {
  34. assert(from <= to);
  35. }
  36. bool Includes(const llvm::APSInt &v) const {
  37. return *first <= v && v <= *second;
  38. }
  39. const llvm::APSInt &From() const {
  40. return *first;
  41. }
  42. const llvm::APSInt &To() const {
  43. return *second;
  44. }
  45. const llvm::APSInt *getConcreteValue() const {
  46. return &From() == &To() ? &From() : NULL;
  47. }
  48. void Profile(llvm::FoldingSetNodeID &ID) const {
  49. ID.AddPointer(&From());
  50. ID.AddPointer(&To());
  51. }
  52. };
  53. class RangeTrait : public llvm::ImutContainerInfo<Range> {
  54. public:
  55. // When comparing if one Range is less than another, we should compare
  56. // the actual APSInt values instead of their pointers. This keeps the order
  57. // consistent (instead of comparing by pointer values) and can potentially
  58. // be used to speed up some of the operations in RangeSet.
  59. static inline bool isLess(key_type_ref lhs, key_type_ref rhs) {
  60. return *lhs.first < *rhs.first || (!(*rhs.first < *lhs.first) &&
  61. *lhs.second < *rhs.second);
  62. }
  63. };
  64. /// RangeSet contains a set of ranges. If the set is empty, then
  65. /// there the value of a symbol is overly constrained and there are no
  66. /// possible values for that symbol.
  67. class RangeSet {
  68. typedef llvm::ImmutableSet<Range, RangeTrait> PrimRangeSet;
  69. PrimRangeSet ranges; // no need to make const, since it is an
  70. // ImmutableSet - this allows default operator=
  71. // to work.
  72. public:
  73. typedef PrimRangeSet::Factory Factory;
  74. typedef PrimRangeSet::iterator iterator;
  75. RangeSet(PrimRangeSet RS) : ranges(RS) {}
  76. iterator begin() const { return ranges.begin(); }
  77. iterator end() const { return ranges.end(); }
  78. bool isEmpty() const { return ranges.isEmpty(); }
  79. /// Construct a new RangeSet representing '{ [from, to] }'.
  80. RangeSet(Factory &F, const llvm::APSInt &from, const llvm::APSInt &to)
  81. : ranges(F.add(F.getEmptySet(), Range(from, to))) {}
  82. /// Profile - Generates a hash profile of this RangeSet for use
  83. /// by FoldingSet.
  84. void Profile(llvm::FoldingSetNodeID &ID) const { ranges.Profile(ID); }
  85. /// getConcreteValue - If a symbol is contrained to equal a specific integer
  86. /// constant then this method returns that value. Otherwise, it returns
  87. /// NULL.
  88. const llvm::APSInt* getConcreteValue() const {
  89. return ranges.isSingleton() ? ranges.begin()->getConcreteValue() : 0;
  90. }
  91. private:
  92. void IntersectInRange(BasicValueFactory &BV, Factory &F,
  93. const llvm::APSInt &Lower,
  94. const llvm::APSInt &Upper,
  95. PrimRangeSet &newRanges,
  96. PrimRangeSet::iterator &i,
  97. PrimRangeSet::iterator &e) const {
  98. // There are six cases for each range R in the set:
  99. // 1. R is entirely before the intersection range.
  100. // 2. R is entirely after the intersection range.
  101. // 3. R contains the entire intersection range.
  102. // 4. R starts before the intersection range and ends in the middle.
  103. // 5. R starts in the middle of the intersection range and ends after it.
  104. // 6. R is entirely contained in the intersection range.
  105. // These correspond to each of the conditions below.
  106. for (/* i = begin(), e = end() */; i != e; ++i) {
  107. if (i->To() < Lower) {
  108. continue;
  109. }
  110. if (i->From() > Upper) {
  111. break;
  112. }
  113. if (i->Includes(Lower)) {
  114. if (i->Includes(Upper)) {
  115. newRanges = F.add(newRanges, Range(BV.getValue(Lower),
  116. BV.getValue(Upper)));
  117. break;
  118. } else
  119. newRanges = F.add(newRanges, Range(BV.getValue(Lower), i->To()));
  120. } else {
  121. if (i->Includes(Upper)) {
  122. newRanges = F.add(newRanges, Range(i->From(), BV.getValue(Upper)));
  123. break;
  124. } else
  125. newRanges = F.add(newRanges, *i);
  126. }
  127. }
  128. }
  129. public:
  130. // Returns a set containing the values in the receiving set, intersected with
  131. // the closed range [Lower, Upper]. Unlike the Range type, this range uses
  132. // modular arithmetic, corresponding to the common treatment of C integer
  133. // overflow. Thus, if the Lower bound is greater than the Upper bound, the
  134. // range is taken to wrap around. This is equivalent to taking the
  135. // intersection with the two ranges [Min, Upper] and [Lower, Max],
  136. // or, alternatively, /removing/ all integers between Upper and Lower.
  137. RangeSet Intersect(BasicValueFactory &BV, Factory &F,
  138. const llvm::APSInt &Lower,
  139. const llvm::APSInt &Upper) const {
  140. PrimRangeSet newRanges = F.getEmptySet();
  141. PrimRangeSet::iterator i = begin(), e = end();
  142. if (Lower <= Upper)
  143. IntersectInRange(BV, F, Lower, Upper, newRanges, i, e);
  144. else {
  145. // The order of the next two statements is important!
  146. // IntersectInRange() does not reset the iteration state for i and e.
  147. // Therefore, the lower range most be handled first.
  148. IntersectInRange(BV, F, BV.getMinValue(Upper), Upper, newRanges, i, e);
  149. IntersectInRange(BV, F, Lower, BV.getMaxValue(Lower), newRanges, i, e);
  150. }
  151. return newRanges;
  152. }
  153. void print(raw_ostream &os) const {
  154. bool isFirst = true;
  155. os << "{ ";
  156. for (iterator i = begin(), e = end(); i != e; ++i) {
  157. if (isFirst)
  158. isFirst = false;
  159. else
  160. os << ", ";
  161. os << '[' << i->From().toString(10) << ", " << i->To().toString(10)
  162. << ']';
  163. }
  164. os << " }";
  165. }
  166. bool operator==(const RangeSet &other) const {
  167. return ranges == other.ranges;
  168. }
  169. };
  170. } // end anonymous namespace
  171. typedef llvm::ImmutableMap<SymbolRef,RangeSet> ConstraintRangeTy;
  172. namespace clang {
  173. namespace ento {
  174. template<>
  175. struct ProgramStateTrait<ConstraintRange>
  176. : public ProgramStatePartialTrait<ConstraintRangeTy> {
  177. static inline void *GDMIndex() { return &ConstraintRangeIndex; }
  178. };
  179. }
  180. }
  181. namespace {
  182. class RangeConstraintManager : public SimpleConstraintManager{
  183. RangeSet GetRange(const ProgramState *state, SymbolRef sym);
  184. public:
  185. RangeConstraintManager(SubEngine &subengine)
  186. : SimpleConstraintManager(subengine) {}
  187. const ProgramState *assumeSymNE(const ProgramState *state, SymbolRef sym,
  188. const llvm::APSInt& Int,
  189. const llvm::APSInt& Adjustment);
  190. const ProgramState *assumeSymEQ(const ProgramState *state, SymbolRef sym,
  191. const llvm::APSInt& Int,
  192. const llvm::APSInt& Adjustment);
  193. const ProgramState *assumeSymLT(const ProgramState *state, SymbolRef sym,
  194. const llvm::APSInt& Int,
  195. const llvm::APSInt& Adjustment);
  196. const ProgramState *assumeSymGT(const ProgramState *state, SymbolRef sym,
  197. const llvm::APSInt& Int,
  198. const llvm::APSInt& Adjustment);
  199. const ProgramState *assumeSymGE(const ProgramState *state, SymbolRef sym,
  200. const llvm::APSInt& Int,
  201. const llvm::APSInt& Adjustment);
  202. const ProgramState *assumeSymLE(const ProgramState *state, SymbolRef sym,
  203. const llvm::APSInt& Int,
  204. const llvm::APSInt& Adjustment);
  205. const llvm::APSInt* getSymVal(const ProgramState *St, SymbolRef sym) const;
  206. // FIXME: Refactor into SimpleConstraintManager?
  207. bool isEqual(const ProgramState *St, SymbolRef sym, const llvm::APSInt& V) const {
  208. const llvm::APSInt *i = getSymVal(St, sym);
  209. return i ? *i == V : false;
  210. }
  211. const ProgramState *removeDeadBindings(const ProgramState *St, SymbolReaper& SymReaper);
  212. void print(const ProgramState *St, raw_ostream &Out,
  213. const char* nl, const char *sep);
  214. private:
  215. RangeSet::Factory F;
  216. };
  217. } // end anonymous namespace
  218. ConstraintManager* ento::CreateRangeConstraintManager(ProgramStateManager&,
  219. SubEngine &subeng) {
  220. return new RangeConstraintManager(subeng);
  221. }
  222. const llvm::APSInt* RangeConstraintManager::getSymVal(const ProgramState *St,
  223. SymbolRef sym) const {
  224. const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(sym);
  225. return T ? T->getConcreteValue() : NULL;
  226. }
  227. /// Scan all symbols referenced by the constraints. If the symbol is not alive
  228. /// as marked in LSymbols, mark it as dead in DSymbols.
  229. const ProgramState*
  230. RangeConstraintManager::removeDeadBindings(const ProgramState *state,
  231. SymbolReaper& SymReaper) {
  232. ConstraintRangeTy CR = state->get<ConstraintRange>();
  233. ConstraintRangeTy::Factory& CRFactory = state->get_context<ConstraintRange>();
  234. for (ConstraintRangeTy::iterator I = CR.begin(), E = CR.end(); I != E; ++I) {
  235. SymbolRef sym = I.getKey();
  236. if (SymReaper.maybeDead(sym))
  237. CR = CRFactory.remove(CR, sym);
  238. }
  239. return state->set<ConstraintRange>(CR);
  240. }
  241. RangeSet
  242. RangeConstraintManager::GetRange(const ProgramState *state, SymbolRef sym) {
  243. if (ConstraintRangeTy::data_type* V = state->get<ConstraintRange>(sym))
  244. return *V;
  245. // Lazily generate a new RangeSet representing all possible values for the
  246. // given symbol type.
  247. QualType T = state->getSymbolManager().getType(sym);
  248. BasicValueFactory& BV = state->getBasicVals();
  249. return RangeSet(F, BV.getMinValue(T), BV.getMaxValue(T));
  250. }
  251. //===------------------------------------------------------------------------===
  252. // assumeSymX methods: public interface for RangeConstraintManager.
  253. //===------------------------------------------------------------------------===/
  254. // The syntax for ranges below is mathematical, using [x, y] for closed ranges
  255. // and (x, y) for open ranges. These ranges are modular, corresponding with
  256. // a common treatment of C integer overflow. This means that these methods
  257. // do not have to worry about overflow; RangeSet::Intersect can handle such a
  258. // "wraparound" range.
  259. // As an example, the range [UINT_MAX-1, 3) contains five values: UINT_MAX-1,
  260. // UINT_MAX, 0, 1, and 2.
  261. const ProgramState*
  262. RangeConstraintManager::assumeSymNE(const ProgramState *state, SymbolRef sym,
  263. const llvm::APSInt& Int,
  264. const llvm::APSInt& Adjustment) {
  265. BasicValueFactory &BV = state->getBasicVals();
  266. llvm::APSInt Lower = Int-Adjustment;
  267. llvm::APSInt Upper = Lower;
  268. --Lower;
  269. ++Upper;
  270. // [Int-Adjustment+1, Int-Adjustment-1]
  271. // Notice that the lower bound is greater than the upper bound.
  272. RangeSet New = GetRange(state, sym).Intersect(BV, F, Upper, Lower);
  273. return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
  274. }
  275. const ProgramState*
  276. RangeConstraintManager::assumeSymEQ(const ProgramState *state, SymbolRef sym,
  277. const llvm::APSInt& Int,
  278. const llvm::APSInt& Adjustment) {
  279. // [Int-Adjustment, Int-Adjustment]
  280. BasicValueFactory &BV = state->getBasicVals();
  281. llvm::APSInt AdjInt = Int-Adjustment;
  282. RangeSet New = GetRange(state, sym).Intersect(BV, F, AdjInt, AdjInt);
  283. return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
  284. }
  285. const ProgramState*
  286. RangeConstraintManager::assumeSymLT(const ProgramState *state, SymbolRef sym,
  287. const llvm::APSInt& Int,
  288. const llvm::APSInt& Adjustment) {
  289. BasicValueFactory &BV = state->getBasicVals();
  290. QualType T = state->getSymbolManager().getType(sym);
  291. const llvm::APSInt &Min = BV.getMinValue(T);
  292. // Special case for Int == Min. This is always false.
  293. if (Int == Min)
  294. return NULL;
  295. llvm::APSInt Lower = Min-Adjustment;
  296. llvm::APSInt Upper = Int-Adjustment;
  297. --Upper;
  298. RangeSet New = GetRange(state, sym).Intersect(BV, F, Lower, Upper);
  299. return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
  300. }
  301. const ProgramState*
  302. RangeConstraintManager::assumeSymGT(const ProgramState *state, SymbolRef sym,
  303. const llvm::APSInt& Int,
  304. const llvm::APSInt& Adjustment) {
  305. BasicValueFactory &BV = state->getBasicVals();
  306. QualType T = state->getSymbolManager().getType(sym);
  307. const llvm::APSInt &Max = BV.getMaxValue(T);
  308. // Special case for Int == Max. This is always false.
  309. if (Int == Max)
  310. return NULL;
  311. llvm::APSInt Lower = Int-Adjustment;
  312. llvm::APSInt Upper = Max-Adjustment;
  313. ++Lower;
  314. RangeSet New = GetRange(state, sym).Intersect(BV, F, Lower, Upper);
  315. return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
  316. }
  317. const ProgramState*
  318. RangeConstraintManager::assumeSymGE(const ProgramState *state, SymbolRef sym,
  319. const llvm::APSInt& Int,
  320. const llvm::APSInt& Adjustment) {
  321. BasicValueFactory &BV = state->getBasicVals();
  322. QualType T = state->getSymbolManager().getType(sym);
  323. const llvm::APSInt &Min = BV.getMinValue(T);
  324. // Special case for Int == Min. This is always feasible.
  325. if (Int == Min)
  326. return state;
  327. const llvm::APSInt &Max = BV.getMaxValue(T);
  328. llvm::APSInt Lower = Int-Adjustment;
  329. llvm::APSInt Upper = Max-Adjustment;
  330. RangeSet New = GetRange(state, sym).Intersect(BV, F, Lower, Upper);
  331. return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
  332. }
  333. const ProgramState*
  334. RangeConstraintManager::assumeSymLE(const ProgramState *state, SymbolRef sym,
  335. const llvm::APSInt& Int,
  336. const llvm::APSInt& Adjustment) {
  337. BasicValueFactory &BV = state->getBasicVals();
  338. QualType T = state->getSymbolManager().getType(sym);
  339. const llvm::APSInt &Max = BV.getMaxValue(T);
  340. // Special case for Int == Max. This is always feasible.
  341. if (Int == Max)
  342. return state;
  343. const llvm::APSInt &Min = BV.getMinValue(T);
  344. llvm::APSInt Lower = Min-Adjustment;
  345. llvm::APSInt Upper = Int-Adjustment;
  346. RangeSet New = GetRange(state, sym).Intersect(BV, F, Lower, Upper);
  347. return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
  348. }
  349. //===------------------------------------------------------------------------===
  350. // Pretty-printing.
  351. //===------------------------------------------------------------------------===/
  352. void RangeConstraintManager::print(const ProgramState *St, raw_ostream &Out,
  353. const char* nl, const char *sep) {
  354. ConstraintRangeTy Ranges = St->get<ConstraintRange>();
  355. if (Ranges.isEmpty()) {
  356. Out << nl << sep << "Ranges are empty." << nl;
  357. return;
  358. }
  359. Out << nl << sep << "Ranges of symbol values:";
  360. for (ConstraintRangeTy::iterator I=Ranges.begin(), E=Ranges.end(); I!=E; ++I){
  361. Out << nl << ' ' << I.getKey() << " : ";
  362. I.getData().print(Out);
  363. }
  364. Out << nl;
  365. }