15 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONSTRAINTMANAGER_H 16 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONSTRAINTMANAGER_H 24 template <
typename Constra
intSMT,
typename SMTExprTy>
39 bool Assumption)
override {
54 return assumeExpr(State, Sym, Assumption ? Exp : Solver->mkNot(Exp));
58 const llvm::APSInt &From,
59 const llvm::APSInt &To,
60 bool InRange)
override {
67 bool Assumption)
override {
109 if (
const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
127 if (!isSat.hasValue() || !isSat.getValue())
131 if (!Solver->getInterpretation(Exp,
Value))
138 : Solver->mkBitvector(
Value,
Value.getBitWidth()),
141 Solver->addConstraint(NotExp);
144 if (!isSat.hasValue() || isNotSat.getValue())
148 return &BVF.getValue(
Value);
151 if (
const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
158 const llvm::APSInt *
Value;
159 if (!(Value =
getSymVal(State, CastSym)))
164 if (
const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
165 const llvm::APSInt *LHS, *RHS;
166 if (
const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
168 RHS = &SIE->getRHS();
169 }
else if (
const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
170 LHS = &ISE->getLHS();
172 }
else if (
const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
175 RHS = LHS ?
getSymVal(State, SSM->getRHS()) :
nullptr;
177 llvm_unreachable(
"Unsupported binary expression to get symbol value!");
183 llvm::APSInt ConvertedLHS, ConvertedRHS;
187 SMTConv::doIntTypeConversion<llvm::APSInt, &SMTConv::castAPSInt>(
188 Solver, Ctx, ConvertedLHS, LTy, ConvertedRHS, RTy);
189 return BVF.
evalAPSInt(BSE->getOpcode(), ConvertedLHS, ConvertedRHS);
192 llvm_unreachable(
"Unsupported expression to get symbol value!");
197 auto CZ = State->get<ConstraintSMT>();
198 auto &CZFactory = State->get_context<ConstraintSMT>();
200 for (
auto I = CZ.begin(), E = CZ.end(); I != E; ++I) {
201 if (SymReaper.
isDead(I->first))
202 CZ = CZFactory.remove(CZ, *I);
205 return State->set<ConstraintSMT>(CZ);
209 const char *sep)
override {
211 auto CZ = St->get<ConstraintSMT>();
213 OS << nl << sep <<
"Constraints:";
214 for (
auto I = CZ.begin(), E = CZ.end(); I != E; ++I) {
215 OS << nl <<
' ' << I->first <<
" : ";
228 const SymExpr *Sym = SymVal->getSymbol();
242 return Solver->isFPSupported();
244 if (isa<SymbolData>(Sym))
249 if (
const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
252 if (
const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
253 if (
const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE))
256 if (
const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE))
259 if (
const SymSymExpr *SSE = dyn_cast<SymSymExpr>(BSE))
264 llvm_unreachable(
"Unsupported expression to reason about!");
268 LLVM_DUMP_METHOD
void dump()
const { Solver->dump(); }
275 if (
checkModel(State, Sym, Exp).isConstrainedTrue())
276 return State->add<ConstraintSMT>(
277 std::make_pair(Sym, static_cast<const SMTExprTy &>(*Exp)));
286 auto CZ = State->get<ConstraintSMT>();
287 auto I = CZ.begin(), IE = CZ.end();
291 std::vector<SMTExprRef> ASTs;
293 SMTExprRef Constraint = Solver->newExprRef(I++->second);
295 Constraint = Solver->mkAnd(Constraint, Solver->newExprRef(I++->second));
298 Solver->addConstraint(Constraint);
306 std::make_pair(Sym, static_cast<const SMTExprTy &>(*Exp)));
308 llvm::FoldingSetNodeID
ID;
309 NewState->get<ConstraintSMT>().Profile(ID);
311 unsigned hash = ID.ComputeHash();
312 auto I =
Cached.find(hash);
330 mutable llvm::DenseMap<unsigned, ConditionTruthVal>
Cached;
bool isConstrainedFalse() const
Return true if the constraint is perfectly constrained to 'false'.
A (possibly-)qualified type.
ConditionTruthVal checkModel(ProgramStateRef State, SymbolRef Sym, const SMTExprRef &Exp) const
bool isDead(SymbolRef sym)
Returns whether or not a symbol has been confirmed dead.
static SMTExprRef getRangeExpr(SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym, const llvm::APSInt &From, const llvm::APSInt &To, bool InRange)
bool isRealFloatingType() const
Floating point categories.
static SMTExprRef getZeroExpr(SMTSolverRef &Solver, ASTContext &Ctx, const SMTExprRef &Exp, QualType Ty, bool Assumption)
static SMTExprRef getExpr(SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym, QualType *RetTy=nullptr, bool *hasComparison=nullptr)
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...
void print(ProgramStateRef St, raw_ostream &OS, const char *nl, const char *sep) override
SMTConstraintManager(clang::ento::SubEngine *SE, clang::ento::SValBuilder &SB, SMTSolverRef &S)
const TargetInfo & getTargetInfo() const
virtual ~SMTConstraintManager()=default
static std::pair< llvm::APSInt, QualType > fixAPSInt(ASTContext &Ctx, const llvm::APSInt &Int)
SVal makeSymbolVal(SymbolRef Sym)
Make an SVal that represents the given symbol.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static SMTExprRef fromData(SMTSolverRef &Solver, const SymbolID ID, const QualType &Ty, uint64_t BitWidth)
Construct an SMTExprRef from a SymbolData.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
const llvm::APSInt & Convert(const llvm::APSInt &To, const llvm::APSInt &From)
Convert - Create a new persistent APSInt with the same value as 'From' but with the bitwidth and sign...
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")...
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 ...
Represents a symbolic expression like 'x' + 3.
ProgramStateRef removeDeadBindings(ProgramStateRef State, SymbolReaper &SymReaper) override
Scan all symbols referenced by the constraints.
LLVM_DUMP_METHOD void dump() const
Dumps SMT formula.
virtual QualType getType() const =0
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...
bool isConstrainedTrue() const
Return true if the constraint is perfectly constrained to 'true'.
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const llvm::fltSemantics & getLongDoubleFormat() const
Exposes information about the current target.
virtual void addStateConstraints(ProgramStateRef State) const
Given a program state, construct the logical conjunction and add it to the solver.
BasicValueFactory & getBasicVals() const
ASTContext & getContext() const
virtual ProgramStateRef assumeExpr(ProgramStateRef State, SymbolRef Sym, const SMTExprRef &Exp)
Represents a cast expression.
SValBuilder & getSValBuilder() const
bool canReasonAbout(SVal X) const override
canReasonAbout - Not all ConstraintManagers can accurately reason about all SVal values.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
llvm::DenseMap< unsigned, ConditionTruthVal > Cached
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
Represents a symbolic expression like 3 - 'x'.
A class responsible for cleaning up unused symbols.
const llvm::APSInt * evalAPSInt(BinaryOperator::Opcode Op, const llvm::APSInt &V1, const llvm::APSInt &V2)
static SMTExprRef fromBinOp(SMTSolverRef &Solver, const SMTExprRef &LHS, const BinaryOperator::Opcode Op, const SMTExprRef &RHS, bool isSigned)
Construct an SMTExprRef from a binary operator.
Dataflow Directional Tag Classes.
Represents a symbolic expression involving a binary operator.
bool isBooleanType() const
Represents symbolic expression that isn't a location.
std::shared_ptr< SMTSolver > SMTSolverRef
Shared pointer for SMTSolvers.
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
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...
bool isComplexIntegerType() const
std::shared_ptr< SMTExpr > SMTExprRef
Shared pointer for SMTExprs, used by SMTSolver API.
Represents a symbolic expression like 'x' + 'y'.
A symbol representing data which can be stored in a memory location (region).