SimpleConstraintManager.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  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/Core/PathSensitive/APSIntType.h"
  16. #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
  17. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
  18. namespace clang {
  19. namespace ento {
  20. SimpleConstraintManager::~SimpleConstraintManager() {}
  21. bool SimpleConstraintManager::canReasonAbout(SVal X) const {
  22. nonloc::SymbolVal *SymVal = dyn_cast<nonloc::SymbolVal>(&X);
  23. if (SymVal && SymVal->isExpression()) {
  24. const SymExpr *SE = SymVal->getSymbol();
  25. if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
  26. switch (SIE->getOpcode()) {
  27. // We don't reason yet about bitwise-constraints on symbolic values.
  28. case BO_And:
  29. case BO_Or:
  30. case BO_Xor:
  31. return false;
  32. // We don't reason yet about these arithmetic constraints on
  33. // symbolic values.
  34. case BO_Mul:
  35. case BO_Div:
  36. case BO_Rem:
  37. case BO_Shl:
  38. case BO_Shr:
  39. return false;
  40. // All other cases.
  41. default:
  42. return true;
  43. }
  44. }
  45. return false;
  46. }
  47. return true;
  48. }
  49. ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state,
  50. DefinedSVal Cond,
  51. bool Assumption) {
  52. if (isa<NonLoc>(Cond))
  53. return assume(state, cast<NonLoc>(Cond), Assumption);
  54. else
  55. return assume(state, cast<Loc>(Cond), Assumption);
  56. }
  57. ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state, Loc cond,
  58. bool assumption) {
  59. state = assumeAux(state, cond, assumption);
  60. return SU.processAssume(state, cond, assumption);
  61. }
  62. ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
  63. Loc Cond, bool Assumption) {
  64. switch (Cond.getSubKind()) {
  65. default:
  66. assert (false && "'Assume' not implemented for this Loc.");
  67. return state;
  68. case loc::MemRegionKind: {
  69. // FIXME: Should this go into the storemanager?
  70. const MemRegion *R = cast<loc::MemRegionVal>(Cond).getRegion();
  71. const SubRegion *SubR = dyn_cast<SubRegion>(R);
  72. while (SubR) {
  73. if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR))
  74. return assumeAuxForSymbol(state, SymR->getSymbol(), Assumption);
  75. SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
  76. }
  77. // FALL-THROUGH.
  78. }
  79. case loc::GotoLabelKind:
  80. return Assumption ? state : NULL;
  81. case loc::ConcreteIntKind: {
  82. bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
  83. bool isFeasible = b ? Assumption : !Assumption;
  84. return isFeasible ? state : NULL;
  85. }
  86. } // end switch
  87. }
  88. ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state,
  89. NonLoc cond,
  90. bool assumption) {
  91. state = assumeAux(state, cond, assumption);
  92. return SU.processAssume(state, cond, assumption);
  93. }
  94. static BinaryOperator::Opcode NegateComparison(BinaryOperator::Opcode op) {
  95. // FIXME: This should probably be part of BinaryOperator, since this isn't
  96. // the only place it's used. (This code was copied from SimpleSValBuilder.cpp.)
  97. switch (op) {
  98. default:
  99. llvm_unreachable("Invalid opcode.");
  100. case BO_LT: return BO_GE;
  101. case BO_GT: return BO_LE;
  102. case BO_LE: return BO_GT;
  103. case BO_GE: return BO_LT;
  104. case BO_EQ: return BO_NE;
  105. case BO_NE: return BO_EQ;
  106. }
  107. }
  108. ProgramStateRef
  109. SimpleConstraintManager::assumeAuxForSymbol(ProgramStateRef State,
  110. SymbolRef Sym, bool Assumption) {
  111. BasicValueFactory &BVF = getBasicVals();
  112. QualType T = Sym->getType(BVF.getContext());
  113. // Don't do anything if this isn't a type we can constrain.
  114. if (!(T->isIntegralOrEnumerationType() || Loc::isLocType(T)))
  115. return State;
  116. if (T->isReferenceType())
  117. return Assumption ? State : NULL;
  118. const llvm::APSInt &zero = BVF.getValue(0, T);
  119. if (Assumption)
  120. return assumeSymNE(State, Sym, zero, zero);
  121. else
  122. return assumeSymEQ(State, Sym, zero, zero);
  123. }
  124. ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
  125. NonLoc Cond,
  126. bool Assumption) {
  127. // We cannot reason about SymSymExprs, and can only reason about some
  128. // SymIntExprs.
  129. if (!canReasonAbout(Cond)) {
  130. // Just add the constraint to the expression without trying to simplify.
  131. SymbolRef sym = Cond.getAsSymExpr();
  132. return assumeAuxForSymbol(state, sym, Assumption);
  133. }
  134. switch (Cond.getSubKind()) {
  135. default:
  136. llvm_unreachable("'Assume' not implemented for this NonLoc");
  137. case nonloc::SymbolValKind: {
  138. nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
  139. SymbolRef sym = SV.getSymbol();
  140. assert(sym);
  141. // Handle SymbolData.
  142. if (!SV.isExpression()) {
  143. return assumeAuxForSymbol(state, sym, Assumption);
  144. // Handle symbolic expression.
  145. } else {
  146. // We can only simplify expressions whose RHS is an integer.
  147. const SymIntExpr *SE = dyn_cast<SymIntExpr>(sym);
  148. if (!SE)
  149. return assumeAuxForSymbol(state, sym, Assumption);
  150. BinaryOperator::Opcode op = SE->getOpcode();
  151. // Implicitly compare non-comparison expressions to 0.
  152. if (!BinaryOperator::isComparisonOp(op))
  153. return assumeAuxForSymbol(state, SE, Assumption);
  154. // From here on out, op is the real comparison we'll be testing.
  155. if (!Assumption)
  156. op = NegateComparison(op);
  157. return assumeSymRel(state, SE->getLHS(), op, SE->getRHS());
  158. }
  159. }
  160. case nonloc::ConcreteIntKind: {
  161. bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
  162. bool isFeasible = b ? Assumption : !Assumption;
  163. return isFeasible ? state : NULL;
  164. }
  165. case nonloc::LocAsIntegerKind:
  166. return assumeAux(state, cast<nonloc::LocAsInteger>(Cond).getLoc(),
  167. Assumption);
  168. } // end switch
  169. }
  170. static void computeAdjustment(SymbolRef &Sym, llvm::APSInt &Adjustment) {
  171. // Is it a "($sym+constant1)" expression?
  172. if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(Sym)) {
  173. BinaryOperator::Opcode Op = SE->getOpcode();
  174. if (Op == BO_Add || Op == BO_Sub) {
  175. Sym = SE->getLHS();
  176. Adjustment = APSIntType(Adjustment).convert(SE->getRHS());
  177. // Don't forget to negate the adjustment if it's being subtracted.
  178. // This should happen /after/ promotion, in case the value being
  179. // subtracted is, say, CHAR_MIN, and the promoted type is 'int'.
  180. if (Op == BO_Sub)
  181. Adjustment = -Adjustment;
  182. }
  183. }
  184. }
  185. ProgramStateRef SimpleConstraintManager::assumeSymRel(ProgramStateRef state,
  186. const SymExpr *LHS,
  187. BinaryOperator::Opcode op,
  188. const llvm::APSInt& Int) {
  189. assert(BinaryOperator::isComparisonOp(op) &&
  190. "Non-comparison ops should be rewritten as comparisons to zero.");
  191. BasicValueFactory &BVF = getBasicVals();
  192. ASTContext &Ctx = BVF.getContext();
  193. // Special case for references, which cannot be null.
  194. QualType Ty = LHS->getType(Ctx);
  195. if (Ty->isReferenceType() && Int == 0) {
  196. switch (op) {
  197. case BO_EQ:
  198. case BO_LE:
  199. case BO_LT:
  200. return NULL;
  201. case BO_NE:
  202. case BO_GT:
  203. case BO_GE:
  204. return state;
  205. default:
  206. llvm_unreachable("We should only be handling comparisons here.");
  207. }
  208. }
  209. // Get the type used for calculating wraparound.
  210. APSIntType WraparoundType = BVF.getAPSIntType(Ty);
  211. // We only handle simple comparisons of the form "$sym == constant"
  212. // or "($sym+constant1) == constant2".
  213. // The adjustment is "constant1" in the above expression. It's used to
  214. // "slide" the solution range around for modular arithmetic. For example,
  215. // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
  216. // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
  217. // the subclasses of SimpleConstraintManager to handle the adjustment.
  218. SymbolRef Sym = LHS;
  219. llvm::APSInt Adjustment = WraparoundType.getZeroValue();
  220. computeAdjustment(Sym, Adjustment);
  221. // Convert the right-hand side integer as necessary.
  222. APSIntType ComparisonType = std::max(WraparoundType, APSIntType(Int));
  223. llvm::APSInt ConvertedInt = ComparisonType.convert(Int);
  224. switch (op) {
  225. default:
  226. // No logic yet for other operators. assume the constraint is feasible.
  227. return state;
  228. case BO_EQ:
  229. return assumeSymEQ(state, Sym, ConvertedInt, Adjustment);
  230. case BO_NE:
  231. return assumeSymNE(state, Sym, ConvertedInt, Adjustment);
  232. case BO_GT:
  233. return assumeSymGT(state, Sym, ConvertedInt, Adjustment);
  234. case BO_GE:
  235. return assumeSymGE(state, Sym, ConvertedInt, Adjustment);
  236. case BO_LT:
  237. return assumeSymLT(state, Sym, ConvertedInt, Adjustment);
  238. case BO_LE:
  239. return assumeSymLE(state, Sym, ConvertedInt, Adjustment);
  240. } // end switch
  241. }
  242. } // end of namespace ento
  243. } // end of namespace clang