RangeConstraintManager.cpp 30 KB

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