SimpleConstraintManager.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. //== SimpleConstraintManager.cpp --------------------------------*- 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 SimpleConstraintManager, a class that holds code shared
  11. // between BasicConstraintManager and RangeConstraintManager.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "SimpleConstraintManager.h"
  15. #include "clang/StaticAnalyzer/PathSensitive/ExprEngine.h"
  16. #include "clang/StaticAnalyzer/PathSensitive/GRState.h"
  17. #include "clang/StaticAnalyzer/PathSensitive/Checker.h"
  18. namespace clang {
  19. namespace ento {
  20. SimpleConstraintManager::~SimpleConstraintManager() {}
  21. bool SimpleConstraintManager::canReasonAbout(SVal X) const {
  22. if (nonloc::SymExprVal *SymVal = dyn_cast<nonloc::SymExprVal>(&X)) {
  23. const SymExpr *SE = SymVal->getSymbolicExpression();
  24. if (isa<SymbolData>(SE))
  25. return true;
  26. if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
  27. switch (SIE->getOpcode()) {
  28. // We don't reason yet about bitwise-constraints on symbolic values.
  29. case BO_And:
  30. case BO_Or:
  31. case BO_Xor:
  32. return false;
  33. // We don't reason yet about these arithmetic constraints on
  34. // symbolic values.
  35. case BO_Mul:
  36. case BO_Div:
  37. case BO_Rem:
  38. case BO_Shl:
  39. case BO_Shr:
  40. return false;
  41. // All other cases.
  42. default:
  43. return true;
  44. }
  45. }
  46. return false;
  47. }
  48. return true;
  49. }
  50. const GRState *SimpleConstraintManager::assume(const GRState *state,
  51. DefinedSVal Cond,
  52. bool Assumption) {
  53. if (isa<NonLoc>(Cond))
  54. return assume(state, cast<NonLoc>(Cond), Assumption);
  55. else
  56. return assume(state, cast<Loc>(Cond), Assumption);
  57. }
  58. const GRState *SimpleConstraintManager::assume(const GRState *state, Loc cond,
  59. bool assumption) {
  60. state = assumeAux(state, cond, assumption);
  61. return SU.processAssume(state, cond, assumption);
  62. }
  63. const GRState *SimpleConstraintManager::assumeAux(const GRState *state,
  64. Loc Cond, bool Assumption) {
  65. BasicValueFactory &BasicVals = state->getBasicVals();
  66. switch (Cond.getSubKind()) {
  67. default:
  68. assert (false && "'Assume' not implemented for this Loc.");
  69. return state;
  70. case loc::MemRegionKind: {
  71. // FIXME: Should this go into the storemanager?
  72. const MemRegion *R = cast<loc::MemRegionVal>(Cond).getRegion();
  73. const SubRegion *SubR = dyn_cast<SubRegion>(R);
  74. while (SubR) {
  75. // FIXME: now we only find the first symbolic region.
  76. if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) {
  77. const llvm::APSInt &zero = BasicVals.getZeroWithPtrWidth();
  78. if (Assumption)
  79. return assumeSymNE(state, SymR->getSymbol(), zero, zero);
  80. else
  81. return assumeSymEQ(state, SymR->getSymbol(), zero, zero);
  82. }
  83. SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
  84. }
  85. // FALL-THROUGH.
  86. }
  87. case loc::GotoLabelKind:
  88. return Assumption ? state : NULL;
  89. case loc::ConcreteIntKind: {
  90. bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
  91. bool isFeasible = b ? Assumption : !Assumption;
  92. return isFeasible ? state : NULL;
  93. }
  94. } // end switch
  95. }
  96. const GRState *SimpleConstraintManager::assume(const GRState *state,
  97. NonLoc cond,
  98. bool assumption) {
  99. state = assumeAux(state, cond, assumption);
  100. return SU.processAssume(state, cond, assumption);
  101. }
  102. static BinaryOperator::Opcode NegateComparison(BinaryOperator::Opcode op) {
  103. // FIXME: This should probably be part of BinaryOperator, since this isn't
  104. // the only place it's used. (This code was copied from SimpleSValBuilder.cpp.)
  105. switch (op) {
  106. default:
  107. assert(false && "Invalid opcode.");
  108. case BO_LT: return BO_GE;
  109. case BO_GT: return BO_LE;
  110. case BO_LE: return BO_GT;
  111. case BO_GE: return BO_LT;
  112. case BO_EQ: return BO_NE;
  113. case BO_NE: return BO_EQ;
  114. }
  115. }
  116. const GRState *SimpleConstraintManager::assumeAux(const GRState *state,
  117. NonLoc Cond,
  118. bool Assumption) {
  119. // We cannot reason about SymSymExprs,
  120. // and can only reason about some SymIntExprs.
  121. if (!canReasonAbout(Cond)) {
  122. // Just return the current state indicating that the path is feasible.
  123. // This may be an over-approximation of what is possible.
  124. return state;
  125. }
  126. BasicValueFactory &BasicVals = state->getBasicVals();
  127. SymbolManager &SymMgr = state->getSymbolManager();
  128. switch (Cond.getSubKind()) {
  129. default:
  130. assert(false && "'Assume' not implemented for this NonLoc");
  131. case nonloc::SymbolValKind: {
  132. nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
  133. SymbolRef sym = SV.getSymbol();
  134. QualType T = SymMgr.getType(sym);
  135. const llvm::APSInt &zero = BasicVals.getValue(0, T);
  136. if (Assumption)
  137. return assumeSymNE(state, sym, zero, zero);
  138. else
  139. return assumeSymEQ(state, sym, zero, zero);
  140. }
  141. case nonloc::SymExprValKind: {
  142. nonloc::SymExprVal V = cast<nonloc::SymExprVal>(Cond);
  143. // For now, we only handle expressions whose RHS is an integer.
  144. // All other expressions are assumed to be feasible.
  145. const SymIntExpr *SE = dyn_cast<SymIntExpr>(V.getSymbolicExpression());
  146. if (!SE)
  147. return state;
  148. BinaryOperator::Opcode op = SE->getOpcode();
  149. // Implicitly compare non-comparison expressions to 0.
  150. if (!BinaryOperator::isComparisonOp(op)) {
  151. QualType T = SymMgr.getType(SE);
  152. const llvm::APSInt &zero = BasicVals.getValue(0, T);
  153. op = (Assumption ? BO_NE : BO_EQ);
  154. return assumeSymRel(state, SE, op, zero);
  155. }
  156. // From here on out, op is the real comparison we'll be testing.
  157. if (!Assumption)
  158. op = NegateComparison(op);
  159. return assumeSymRel(state, SE->getLHS(), op, SE->getRHS());
  160. }
  161. case nonloc::ConcreteIntKind: {
  162. bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
  163. bool isFeasible = b ? Assumption : !Assumption;
  164. return isFeasible ? state : NULL;
  165. }
  166. case nonloc::LocAsIntegerKind:
  167. return assumeAux(state, cast<nonloc::LocAsInteger>(Cond).getLoc(),
  168. Assumption);
  169. } // end switch
  170. }
  171. const GRState *SimpleConstraintManager::assumeSymRel(const GRState *state,
  172. const SymExpr *LHS,
  173. BinaryOperator::Opcode op,
  174. const llvm::APSInt& Int) {
  175. assert(BinaryOperator::isComparisonOp(op) &&
  176. "Non-comparison ops should be rewritten as comparisons to zero.");
  177. // We only handle simple comparisons of the form "$sym == constant"
  178. // or "($sym+constant1) == constant2".
  179. // The adjustment is "constant1" in the above expression. It's used to
  180. // "slide" the solution range around for modular arithmetic. For example,
  181. // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
  182. // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
  183. // the subclasses of SimpleConstraintManager to handle the adjustment.
  184. llvm::APSInt Adjustment;
  185. // First check if the LHS is a simple symbol reference.
  186. SymbolRef Sym = dyn_cast<SymbolData>(LHS);
  187. if (Sym) {
  188. Adjustment = 0;
  189. } else {
  190. // Next, see if it's a "($sym+constant1)" expression.
  191. const SymIntExpr *SE = dyn_cast<SymIntExpr>(LHS);
  192. // We don't handle "($sym1+$sym2)".
  193. // Give up and assume the constraint is feasible.
  194. if (!SE)
  195. return state;
  196. // We don't handle "(<expr>+constant1)".
  197. // Give up and assume the constraint is feasible.
  198. Sym = dyn_cast<SymbolData>(SE->getLHS());
  199. if (!Sym)
  200. return state;
  201. // Get the constant out of the expression "($sym+constant1)".
  202. switch (SE->getOpcode()) {
  203. case BO_Add:
  204. Adjustment = SE->getRHS();
  205. break;
  206. case BO_Sub:
  207. Adjustment = -SE->getRHS();
  208. break;
  209. default:
  210. // We don't handle non-additive operators.
  211. // Give up and assume the constraint is feasible.
  212. return state;
  213. }
  214. }
  215. // FIXME: This next section is a hack. It silently converts the integers to
  216. // be of the same type as the symbol, which is not always correct. Really the
  217. // comparisons should be performed using the Int's type, then mapped back to
  218. // the symbol's range of values.
  219. GRStateManager &StateMgr = state->getStateManager();
  220. ASTContext &Ctx = StateMgr.getContext();
  221. QualType T = Sym->getType(Ctx);
  222. assert(T->isIntegerType() || Loc::IsLocType(T));
  223. unsigned bitwidth = Ctx.getTypeSize(T);
  224. bool isSymUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
  225. // Convert the adjustment.
  226. Adjustment.setIsUnsigned(isSymUnsigned);
  227. Adjustment = Adjustment.extOrTrunc(bitwidth);
  228. // Convert the right-hand side integer.
  229. llvm::APSInt ConvertedInt(Int, isSymUnsigned);
  230. ConvertedInt = ConvertedInt.extOrTrunc(bitwidth);
  231. switch (op) {
  232. default:
  233. // No logic yet for other operators. assume the constraint is feasible.
  234. return state;
  235. case BO_EQ:
  236. return assumeSymEQ(state, Sym, ConvertedInt, Adjustment);
  237. case BO_NE:
  238. return assumeSymNE(state, Sym, ConvertedInt, Adjustment);
  239. case BO_GT:
  240. return assumeSymGT(state, Sym, ConvertedInt, Adjustment);
  241. case BO_GE:
  242. return assumeSymGE(state, Sym, ConvertedInt, Adjustment);
  243. case BO_LT:
  244. return assumeSymLT(state, Sym, ConvertedInt, Adjustment);
  245. case BO_LE:
  246. return assumeSymLE(state, Sym, ConvertedInt, Adjustment);
  247. } // end switch
  248. }
  249. } // end of namespace ento
  250. } // end of namespace clang