SMTConstraintManager.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. //== SMTConstraintManager.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. #include "clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h"
  10. #include "clang/Basic/TargetInfo.h"
  11. #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
  12. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
  13. using namespace clang;
  14. using namespace ento;
  15. ProgramStateRef SMTConstraintManager::assumeSym(ProgramStateRef State,
  16. SymbolRef Sym,
  17. bool Assumption) {
  18. ASTContext &Ctx = getBasicVals().getContext();
  19. QualType RetTy;
  20. bool hasComparison;
  21. SMTExprRef Exp = Solver->getExpr(Ctx, Sym, &RetTy, &hasComparison);
  22. // Create zero comparison for implicit boolean cast, with reversed assumption
  23. if (!hasComparison && !RetTy->isBooleanType())
  24. return assumeExpr(State, Sym,
  25. Solver->getZeroExpr(Ctx, Exp, RetTy, !Assumption));
  26. return assumeExpr(State, Sym, Assumption ? Exp : Solver->mkNot(Exp));
  27. }
  28. ProgramStateRef SMTConstraintManager::assumeSymInclusiveRange(
  29. ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
  30. const llvm::APSInt &To, bool InRange) {
  31. ASTContext &Ctx = getBasicVals().getContext();
  32. return assumeExpr(State, Sym,
  33. Solver->getRangeExpr(Ctx, Sym, From, To, InRange));
  34. }
  35. ProgramStateRef
  36. SMTConstraintManager::assumeSymUnsupported(ProgramStateRef State, SymbolRef Sym,
  37. bool Assumption) {
  38. // Skip anything that is unsupported
  39. return State;
  40. }
  41. ConditionTruthVal SMTConstraintManager::checkNull(ProgramStateRef State,
  42. SymbolRef Sym) {
  43. ASTContext &Ctx = getBasicVals().getContext();
  44. QualType RetTy;
  45. // The expression may be casted, so we cannot call getZ3DataExpr() directly
  46. SMTExprRef VarExp = Solver->getExpr(Ctx, Sym, &RetTy);
  47. SMTExprRef Exp = Solver->getZeroExpr(Ctx, VarExp, RetTy, /*Assumption=*/true);
  48. // Negate the constraint
  49. SMTExprRef NotExp =
  50. Solver->getZeroExpr(Ctx, VarExp, RetTy, /*Assumption=*/false);
  51. Solver->reset();
  52. addStateConstraints(State);
  53. Solver->push();
  54. Solver->addConstraint(Exp);
  55. ConditionTruthVal isSat = Solver->check();
  56. Solver->pop();
  57. Solver->addConstraint(NotExp);
  58. ConditionTruthVal isNotSat = Solver->check();
  59. // Zero is the only possible solution
  60. if (isSat.isConstrainedTrue() && isNotSat.isConstrainedFalse())
  61. return true;
  62. // Zero is not a solution
  63. if (isSat.isConstrainedFalse() && isNotSat.isConstrainedTrue())
  64. return false;
  65. // Zero may be a solution
  66. return ConditionTruthVal();
  67. }
  68. const llvm::APSInt *SMTConstraintManager::getSymVal(ProgramStateRef State,
  69. SymbolRef Sym) const {
  70. BasicValueFactory &BVF = getBasicVals();
  71. ASTContext &Ctx = BVF.getContext();
  72. if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
  73. QualType Ty = Sym->getType();
  74. assert(!Ty->isRealFloatingType());
  75. llvm::APSInt Value(Ctx.getTypeSize(Ty),
  76. !Ty->isSignedIntegerOrEnumerationType());
  77. SMTExprRef Exp =
  78. Solver->fromData(SD->getSymbolID(), Ty, Ctx.getTypeSize(Ty));
  79. Solver->reset();
  80. addStateConstraints(State);
  81. // Constraints are unsatisfiable
  82. ConditionTruthVal isSat = Solver->check();
  83. if (!isSat.isConstrainedTrue())
  84. return nullptr;
  85. // Model does not assign interpretation
  86. if (!Solver->getInterpretation(Exp, Value))
  87. return nullptr;
  88. // A value has been obtained, check if it is the only value
  89. SMTExprRef NotExp = Solver->fromBinOp(
  90. Exp, BO_NE,
  91. Ty->isBooleanType() ? Solver->fromBoolean(Value.getBoolValue())
  92. : Solver->fromAPSInt(Value),
  93. false);
  94. Solver->addConstraint(NotExp);
  95. ConditionTruthVal isNotSat = Solver->check();
  96. if (isNotSat.isConstrainedTrue())
  97. return nullptr;
  98. // This is the only solution, store it
  99. return &BVF.getValue(Value);
  100. }
  101. if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
  102. SymbolRef CastSym = SC->getOperand();
  103. QualType CastTy = SC->getType();
  104. // Skip the void type
  105. if (CastTy->isVoidType())
  106. return nullptr;
  107. const llvm::APSInt *Value;
  108. if (!(Value = getSymVal(State, CastSym)))
  109. return nullptr;
  110. return &BVF.Convert(SC->getType(), *Value);
  111. }
  112. if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
  113. const llvm::APSInt *LHS, *RHS;
  114. if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
  115. LHS = getSymVal(State, SIE->getLHS());
  116. RHS = &SIE->getRHS();
  117. } else if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
  118. LHS = &ISE->getLHS();
  119. RHS = getSymVal(State, ISE->getRHS());
  120. } else if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
  121. // Early termination to avoid expensive call
  122. LHS = getSymVal(State, SSM->getLHS());
  123. RHS = LHS ? getSymVal(State, SSM->getRHS()) : nullptr;
  124. } else {
  125. llvm_unreachable("Unsupported binary expression to get symbol value!");
  126. }
  127. if (!LHS || !RHS)
  128. return nullptr;
  129. llvm::APSInt ConvertedLHS, ConvertedRHS;
  130. QualType LTy, RTy;
  131. std::tie(ConvertedLHS, LTy) = Solver->fixAPSInt(Ctx, *LHS);
  132. std::tie(ConvertedRHS, RTy) = Solver->fixAPSInt(Ctx, *RHS);
  133. Solver->doIntTypeConversion<llvm::APSInt, &SMTSolver::castAPSInt>(
  134. Ctx, ConvertedLHS, LTy, ConvertedRHS, RTy);
  135. return BVF.evalAPSInt(BSE->getOpcode(), ConvertedLHS, ConvertedRHS);
  136. }
  137. llvm_unreachable("Unsupported expression to get symbol value!");
  138. }
  139. ConditionTruthVal
  140. SMTConstraintManager::checkModel(ProgramStateRef State,
  141. const SMTExprRef &Exp) const {
  142. Solver->reset();
  143. Solver->addConstraint(Exp);
  144. addStateConstraints(State);
  145. return Solver->check();
  146. }