clang  7.0.0
SMTConstraintManager.cpp
Go to the documentation of this file.
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 
11 #include "clang/Basic/TargetInfo.h"
14 
15 using namespace clang;
16 using namespace ento;
17 
19  SymbolRef Sym,
20  bool Assumption) {
22 
23  QualType RetTy;
24  bool hasComparison;
25 
26  SMTExprRef Exp = Solver->getExpr(Ctx, Sym, &RetTy, &hasComparison);
27 
28  // Create zero comparison for implicit boolean cast, with reversed assumption
29  if (!hasComparison && !RetTy->isBooleanType())
30  return assumeExpr(State, Sym,
31  Solver->getZeroExpr(Ctx, Exp, RetTy, !Assumption));
32 
33  return assumeExpr(State, Sym, Assumption ? Exp : Solver->mkNot(Exp));
34 }
35 
37  ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
38  const llvm::APSInt &To, bool InRange) {
40  return assumeExpr(State, Sym,
41  Solver->getRangeExpr(Ctx, Sym, From, To, InRange));
42 }
43 
46  bool Assumption) {
47  // Skip anything that is unsupported
48  return State;
49 }
50 
52  SymbolRef Sym) {
54 
55  QualType RetTy;
56  // The expression may be casted, so we cannot call getZ3DataExpr() directly
57  SMTExprRef VarExp = Solver->getExpr(Ctx, Sym, &RetTy);
58  SMTExprRef Exp = Solver->getZeroExpr(Ctx, VarExp, RetTy, /*Assumption=*/true);
59 
60  // Negate the constraint
61  SMTExprRef NotExp =
62  Solver->getZeroExpr(Ctx, VarExp, RetTy, /*Assumption=*/false);
63 
64  Solver->reset();
65  addStateConstraints(State);
66 
67  Solver->push();
68  Solver->addConstraint(Exp);
69  ConditionTruthVal isSat = Solver->check();
70 
71  Solver->pop();
72  Solver->addConstraint(NotExp);
73  ConditionTruthVal isNotSat = Solver->check();
74 
75  // Zero is the only possible solution
76  if (isSat.isConstrainedTrue() && isNotSat.isConstrainedFalse())
77  return true;
78 
79  // Zero is not a solution
80  if (isSat.isConstrainedFalse() && isNotSat.isConstrainedTrue())
81  return false;
82 
83  // Zero may be a solution
84  return ConditionTruthVal();
85 }
86 
88  SymbolRef Sym) const {
90  ASTContext &Ctx = BVF.getContext();
91 
92  if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
93  QualType Ty = Sym->getType();
94  assert(!Ty->isRealFloatingType());
95  llvm::APSInt Value(Ctx.getTypeSize(Ty),
97 
98  SMTExprRef Exp =
99  Solver->fromData(SD->getSymbolID(), Ty, Ctx.getTypeSize(Ty));
100 
101  Solver->reset();
102  addStateConstraints(State);
103 
104  // Constraints are unsatisfiable
105  ConditionTruthVal isSat = Solver->check();
106  if (!isSat.isConstrainedTrue())
107  return nullptr;
108 
109  // Model does not assign interpretation
110  if (!Solver->getInterpretation(Exp, Value))
111  return nullptr;
112 
113  // A value has been obtained, check if it is the only value
114  SMTExprRef NotExp = Solver->fromBinOp(
115  Exp, BO_NE,
116  Ty->isBooleanType() ? Solver->fromBoolean(Value.getBoolValue())
117  : Solver->fromAPSInt(Value),
118  false);
119 
120  Solver->addConstraint(NotExp);
121 
122  ConditionTruthVal isNotSat = Solver->check();
123  if (isNotSat.isConstrainedTrue())
124  return nullptr;
125 
126  // This is the only solution, store it
127  return &BVF.getValue(Value);
128  }
129 
130  if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
131  SymbolRef CastSym = SC->getOperand();
132  QualType CastTy = SC->getType();
133  // Skip the void type
134  if (CastTy->isVoidType())
135  return nullptr;
136 
137  const llvm::APSInt *Value;
138  if (!(Value = getSymVal(State, CastSym)))
139  return nullptr;
140  return &BVF.Convert(SC->getType(), *Value);
141  }
142 
143  if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
144  const llvm::APSInt *LHS, *RHS;
145  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
146  LHS = getSymVal(State, SIE->getLHS());
147  RHS = &SIE->getRHS();
148  } else if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
149  LHS = &ISE->getLHS();
150  RHS = getSymVal(State, ISE->getRHS());
151  } else if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
152  // Early termination to avoid expensive call
153  LHS = getSymVal(State, SSM->getLHS());
154  RHS = LHS ? getSymVal(State, SSM->getRHS()) : nullptr;
155  } else {
156  llvm_unreachable("Unsupported binary expression to get symbol value!");
157  }
158 
159  if (!LHS || !RHS)
160  return nullptr;
161 
162  llvm::APSInt ConvertedLHS, ConvertedRHS;
163  QualType LTy, RTy;
164  std::tie(ConvertedLHS, LTy) = Solver->fixAPSInt(Ctx, *LHS);
165  std::tie(ConvertedRHS, RTy) = Solver->fixAPSInt(Ctx, *RHS);
166  Solver->doIntTypeConversion<llvm::APSInt, &SMTSolver::castAPSInt>(
167  Ctx, ConvertedLHS, LTy, ConvertedRHS, RTy);
168  return BVF.evalAPSInt(BSE->getOpcode(), ConvertedLHS, ConvertedRHS);
169  }
170 
171  llvm_unreachable("Unsupported expression to get symbol value!");
172 }
173 
176  const SMTExprRef &Exp) const {
177  Solver->reset();
178  Solver->addConstraint(Exp);
179  addStateConstraints(State);
180  return Solver->check();
181 }
bool isConstrainedFalse() const
Return true if the constraint is perfectly constrained to &#39;false&#39;.
A (possibly-)qualified type.
Definition: Type.h:655
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:1941
ProgramStateRef assumeSymUnsupported(ProgramStateRef State, SymbolRef Sym, bool Assumption) override
Given a symbolic expression that cannot be reasoned about, assume that it is zero/nonzero and add it ...
ConditionTruthVal checkModel(ProgramStateRef State, const SMTExprRef &Exp) const
Symbolic value.
Definition: SymExpr.h:30
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:150
LineState State
const llvm::APSInt & Convert(const llvm::APSInt &To, const llvm::APSInt &From)
Convert - Create a new persistent APSInt with the same value as &#39;From&#39; but with the bitwidth and sign...
llvm::APSInt castAPSInt(const llvm::APSInt &V, QualType ToTy, uint64_t ToWidth, QualType FromTy, uint64_t FromWidth)
Definition: SMTSolver.h:321
Represents a symbolic expression like &#39;x&#39; + 3.
virtual QualType getType() const =0
bool isConstrainedTrue() const
Return true if the constraint is perfectly constrained to &#39;true&#39;.
BasicValueFactory & getBasicVals() const
Represents a cast expression.
ProgramStateRef assumeSymInclusiveRange(ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From, const llvm::APSInt &To, bool InRange) override
Given a symbolic expression within the range [From, To], assume that it is true/false and generate th...
virtual void addStateConstraints(ProgramStateRef State) const =0
Given a program state, construct the logical conjunction and add it to the solver.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
Definition: Type.cpp:1864
Represents a symbolic expression like 3 - &#39;x&#39;.
const llvm::APSInt * getSymVal(ProgramStateRef State, SymbolRef Sym) const override
If a symbol is perfectly constrained to a constant, attempt to return the concrete value...
const llvm::APSInt * evalAPSInt(BinaryOperator::Opcode Op, const llvm::APSInt &V1, const llvm::APSInt &V2)
Dataflow Directional Tag Classes.
Represents a symbolic expression involving a binary operator.
bool isBooleanType() const
Definition: Type.h:6453
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2052
bool isVoidType() const
Definition: Type.h:6340
ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override
Returns whether or not a symbol is known to be null ("true"), known to be non-null ("false")...
Defines the clang::TargetInfo interface.
std::shared_ptr< SMTExpr > SMTExprRef
Shared pointer for SMTExprs, used by SMTSolver API.
Definition: SMTExpr.h:57
ProgramStateRef assumeSym(ProgramStateRef state, SymbolRef Sym, bool Assumption) override
Given a symbolic expression that can be reasoned about, assume that it is true/false and generate the...
virtual ProgramStateRef assumeExpr(ProgramStateRef State, SymbolRef Sym, const SMTExprRef &Exp)=0
Represents a symbolic expression like &#39;x&#39; + &#39;y&#39;.
A symbol representing data which can be stored in a memory location (region).
Definition: SymExpr.h:117