llvm::SMTSortRef
mkSort(llvm::SMTSolverRef &Solver,
28 const QualType&Ty,
unsignedBitWidth) {
30 returnSolver->getBoolSort();
33 returnSolver->getFloatSort(BitWidth);
35 returnSolver->getBitvectorSort(BitWidth);
39 static inlinellvm::SMTExprRef
fromUnOp(llvm::SMTSolverRef &Solver,
41 constllvm::SMTExprRef &Exp) {
44 returnSolver->mkBVNeg(Exp);
47 returnSolver->mkBVNot(Exp);
50 returnSolver->mkNot(Exp);
54llvm_unreachable(
"Unimplemented opcode");
58 static inlinellvm::SMTExprRef
fromFloatUnOp(llvm::SMTSolverRef &Solver,
60 constllvm::SMTExprRef &Exp) {
63 returnSolver->mkFPNeg(Exp);
70llvm_unreachable(
"Unimplemented opcode");
74 static inlinellvm::SMTExprRef
76 conststd::vector<llvm::SMTExprRef> &ASTs) {
77assert(!ASTs.empty());
79 if(Op != BO_LAnd && Op != BO_LOr)
80llvm_unreachable(
"Unimplemented opcode");
82llvm::SMTExprRef res = ASTs.front();
83 for(std::size_t i = 1; i < ASTs.size(); ++i)
84res = (Op == BO_LAnd) ? Solver->mkAnd(res, ASTs[i])
85: Solver->mkOr(res, ASTs[i]);
90 static inlinellvm::SMTExprRef
fromBinOp(llvm::SMTSolverRef &Solver,
91 constllvm::SMTExprRef &LHS,
93 constllvm::SMTExprRef &RHS,
95assert(*Solver->getSort(LHS) == *Solver->getSort(RHS) &&
96 "AST's must have the same sort!");
101 returnSolver->mkBVMul(LHS, RHS);
104 returnisSigned ? Solver->mkBVSDiv(LHS, RHS) : Solver->mkBVUDiv(LHS, RHS);
107 returnisSigned ? Solver->mkBVSRem(LHS, RHS) : Solver->mkBVURem(LHS, RHS);
111 returnSolver->mkBVAdd(LHS, RHS);
114 returnSolver->mkBVSub(LHS, RHS);
118 returnSolver->mkBVShl(LHS, RHS);
121 returnisSigned ? Solver->mkBVAshr(LHS, RHS) : Solver->mkBVLshr(LHS, RHS);
125 returnisSigned ? Solver->mkBVSlt(LHS, RHS) : Solver->mkBVUlt(LHS, RHS);
128 returnisSigned ? Solver->mkBVSgt(LHS, RHS) : Solver->mkBVUgt(LHS, RHS);
131 returnisSigned ? Solver->mkBVSle(LHS, RHS) : Solver->mkBVUle(LHS, RHS);
134 returnisSigned ? Solver->mkBVSge(LHS, RHS) : Solver->mkBVUge(LHS, RHS);
138 returnSolver->mkEqual(LHS, RHS);
142 fromBinOp(Solver, LHS, BO_EQ, RHS, isSigned));
146 returnSolver->mkBVAnd(LHS, RHS);
149 returnSolver->mkBVXor(LHS, RHS);
152 returnSolver->mkBVOr(LHS, RHS);
156 returnSolver->mkAnd(LHS, RHS);
159 returnSolver->mkOr(LHS, RHS);
163llvm_unreachable(
"Unimplemented opcode");
168 static inlinellvm::SMTExprRef
171 constllvm::APFloat::fltCategory &RHS) {
176 casellvm::APFloat::fcInfinity:
177 returnSolver->mkFPIsInfinite(LHS);
179 casellvm::APFloat::fcNaN:
180 returnSolver->mkFPIsNaN(LHS);
182 casellvm::APFloat::fcNormal:
183 returnSolver->mkFPIsNormal(LHS);
185 casellvm::APFloat::fcZero:
186 returnSolver->mkFPIsZero(LHS);
197llvm_unreachable(
"Unimplemented opcode");
202 constllvm::SMTExprRef &LHS,
204 constllvm::SMTExprRef &RHS) {
205assert(*Solver->getSort(LHS) == *Solver->getSort(RHS) &&
206 "AST's must have the same sort!");
211 returnSolver->mkFPMul(LHS, RHS);
214 returnSolver->mkFPDiv(LHS, RHS);
217 returnSolver->mkFPRem(LHS, RHS);
221 returnSolver->mkFPAdd(LHS, RHS);
224 returnSolver->mkFPSub(LHS, RHS);
228 returnSolver->mkFPLt(LHS, RHS);
231 returnSolver->mkFPGt(LHS, RHS);
234 returnSolver->mkFPLe(LHS, RHS);
237 returnSolver->mkFPGe(LHS, RHS);
241 returnSolver->mkFPEqual(LHS, RHS);
250 return fromBinOp(Solver, LHS, Op, RHS,
false);
255llvm_unreachable(
"Unimplemented opcode");
260 static inlinellvm::SMTExprRef
fromCast(llvm::SMTSolverRef &Solver,
261 constllvm::SMTExprRef &Exp,
264uint64_t FromBitWidth) {
272assert(ToBitWidth > 0 &&
"BitWidth must be positive!");
273 returnSolver->mkIte(
274Exp, Solver->mkBitvector(llvm::APSInt(
"1"), ToBitWidth),
275Solver->mkBitvector(llvm::APSInt(
"0"), ToBitWidth));
278 if(ToBitWidth > FromBitWidth)
280? Solver->mkBVSignExt(ToBitWidth - FromBitWidth, Exp)
281: Solver->mkBVZeroExt(ToBitWidth - FromBitWidth, Exp);
283 if(ToBitWidth < FromBitWidth)
284 returnSolver->mkBVExtract(ToBitWidth - 1, 0, Exp);
291 if(ToBitWidth != FromBitWidth)
292 returnSolver->mkFPtoFP(Exp, Solver->getFloatSort(ToBitWidth));
298llvm::SMTSortRef Sort = Solver->getFloatSort(ToBitWidth);
300? Solver->mkSBVtoFP(Exp, Sort)
301: Solver->mkUBVtoFP(Exp, Sort);
306? Solver->mkFPtoSBV(Exp, ToBitWidth)
307: Solver->mkFPtoUBV(Exp, ToBitWidth);
309llvm_unreachable(
"Unsupported explicit type cast!");
313 static inlinellvm::APSInt
castAPSInt(llvm::SMTSolverRef &Solver,
316uint64_t FromWidth) {
322 static inlinellvm::SMTExprRef
326 constuint64_t BitWidth = Ctx.getTypeSize(Ty);
329llvm::raw_svector_ostream
OS(Str);
331 returnSolver->mkSymbol(Str.c_str(),
mkSort(Solver, Ty, BitWidth));
335 static inlinellvm::SMTExprRef
getCastExpr(llvm::SMTSolverRef &Solver,
337 constllvm::SMTExprRef &Exp,
339 return fromCast(Solver, Exp, ToTy, Ctx.getTypeSize(ToTy), FromTy,
340Ctx.getTypeSize(FromTy));
345 static inlinellvm::SMTExprRef
347 constllvm::SMTExprRef &LHS,
QualTypeLTy,
350llvm::SMTExprRef NewLHS = LHS;
351llvm::SMTExprRef NewRHS = RHS;
369*RetTy = Ctx.getPointerDiffType();
389 if(
const SymIntExpr*SIE = dyn_cast<SymIntExpr>(BSE)) {
390llvm::SMTExprRef LHS =
391 getSymExpr(Solver, Ctx, SIE->getLHS(), <y, hasComparison);
392llvm::APSInt NewRInt;
393std::tie(NewRInt, RTy) =
fixAPSInt(Ctx, SIE->getRHS());
394llvm::SMTExprRef RHS =
395Solver->mkBitvector(NewRInt, NewRInt.getBitWidth());
396 return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
399 if(
const IntSymExpr*ISE = dyn_cast<IntSymExpr>(BSE)) {
400llvm::APSInt NewLInt;
401std::tie(NewLInt, LTy) =
fixAPSInt(Ctx, ISE->getLHS());
402llvm::SMTExprRef LHS =
403Solver->mkBitvector(NewLInt, NewLInt.getBitWidth());
404llvm::SMTExprRef RHS =
405 getSymExpr(Solver, Ctx, ISE->getRHS(), &RTy, hasComparison);
406 return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
409 if(
const SymSymExpr*SSM = dyn_cast<SymSymExpr>(BSE)) {
410llvm::SMTExprRef LHS =
411 getSymExpr(Solver, Ctx, SSM->getLHS(), <y, hasComparison);
412llvm::SMTExprRef RHS =
413 getSymExpr(Solver, Ctx, SSM->getRHS(), &RTy, hasComparison);
414 return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
417llvm_unreachable(
"Unsupported BinarySymExpr type!");
422 static inlinellvm::SMTExprRef
getSymExpr(llvm::SMTSolverRef &Solver,
425 bool*hasComparison) {
426 if(
const SymbolData*SD = dyn_cast<SymbolData>(Sym)) {
433 if(
const SymbolCast*SC = dyn_cast<SymbolCast>(Sym)) {
438llvm::SMTExprRef Exp =
439 getSymExpr(Solver, Ctx, SC->getOperand(), &FromTy, hasComparison);
445*hasComparison =
false;
449 if(
const UnarySymExpr*USE = dyn_cast<UnarySymExpr>(Sym)) {
454llvm::SMTExprRef OperandExp =
455 getSymExpr(Solver, Ctx, USE->getOperand(), &OperandTy, hasComparison);
456llvm::SMTExprRef UnaryExp =
459:
fromUnOp(Solver, USE->getOpcode(), OperandExp);
465 if(Ctx.getTypeSize(OperandTy) != Ctx.getTypeSize(Sym->
getType())) {
467*hasComparison =
false;
473 if(
const BinarySymExpr*BSE = dyn_cast<BinarySymExpr>(Sym)) {
474llvm::SMTExprRef Exp =
482llvm_unreachable(
"Unsupported SymbolRef type!");
489 static inlinellvm::SMTExprRef
getExpr(llvm::SMTSolverRef &Solver,
492 bool*hasComparison =
nullptr) {
494*hasComparison =
false;
497 return getSymExpr(Solver, Ctx, Sym, RetTy, hasComparison);
501 static inlinellvm::SMTExprRef
getZeroExpr(llvm::SMTSolverRef &Solver,
503 constllvm::SMTExprRef &Exp,
507llvm::APFloat::getZero(Ctx.getFloatTypeSemantics(Ty));
509Solver->mkFloat(Zero));
518 returnAssumption ?
fromUnOp(Solver, UO_LNot, Exp) : Exp;
521Solver, Exp, Assumption ? BO_EQ : BO_NE,
522Solver->mkBitvector(llvm::APSInt(
"0"), Ctx.getTypeSize(Ty)),
526llvm_unreachable(
"Unsupported type for zero value!");
531 static inlinellvm::SMTExprRef
533 constllvm::APSInt &From,
constllvm::APSInt &To,
boolInRange) {
536llvm::APSInt NewFromInt;
537std::tie(NewFromInt, FromTy) =
fixAPSInt(Ctx, From);
538llvm::SMTExprRef FromExp =
539Solver->mkBitvector(NewFromInt, NewFromInt.getBitWidth());
543llvm::SMTExprRef Exp =
getExpr(Solver, Ctx, Sym, &SymTy);
547 return getBinExpr(Solver, Ctx, Exp, SymTy, InRange ? BO_EQ : BO_NE,
548FromExp, FromTy,
nullptr);
551llvm::APSInt NewToInt;
552std::tie(NewToInt, ToTy) =
fixAPSInt(Ctx, To);
553llvm::SMTExprRef ToExp =
554Solver->mkBitvector(NewToInt, NewToInt.getBitWidth());
555assert(FromTy == ToTy &&
"Range values have different types!");
558llvm::SMTExprRef LHS =
559 getBinExpr(Solver, Ctx, Exp, SymTy, InRange ? BO_GE : BO_LT, FromExp,
561llvm::SMTExprRef RHS =
getBinExpr(Solver, Ctx, Exp, SymTy,
562InRange ? BO_LE : BO_GT, ToExp, ToTy,
565 return fromBinOp(Solver, LHS, InRange ? BO_LAnd : BO_LOr, RHS,
572 constllvm::APSInt &Int) {
573 returnCtx.getIntTypeForBitwidth(Int.getBitWidth(), Int.isSigned());
577 static inlinestd::pair<llvm::APSInt, QualType>
584 if(Int.getBitWidth() == 1 &&
getAPSIntType(Ctx, Int).isNull()) {
585NewInt = Int.extend(Ctx.getTypeSize(Ctx.BoolTy));
597llvm::SMTExprRef &RHS,
QualType<y,
599assert(!LTy.
isNull() && !RTy.
isNull() &&
"Input type is null!");
605SMTConv::doIntTypeConversion<llvm::SMTExprRef, &fromCast>(
606Solver, Ctx, LHS, LTy, RHS, RTy);
611SMTConv::doFloatTypeConversion<llvm::SMTExprRef, &fromCast>(
612Solver, Ctx, LHS, LTy, RHS, RTy);
622uint64_t LBitWidth = Ctx.getTypeSize(LTy);
623uint64_t RBitWidth = Ctx.getTypeSize(RTy);
632LHS =
fromCast(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
635RHS =
fromCast(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
645assert((Ctx.getTypeSize(LTy) == Ctx.getTypeSize(RTy)) &&
646 "Pointer types have different bitwidths!");
670 template<
typename T,
T(*doCast)(llvm::SMTSolverRef &Solver,
const T&,
675uint64_t LBitWidth = Ctx.getTypeSize(LTy);
676uint64_t RBitWidth = Ctx.getTypeSize(RTy);
678assert(!LTy.
isNull() && !RTy.
isNull() &&
"Input type is null!");
681 if(Ctx.isPromotableIntegerType(LTy)) {
682 QualTypeNewTy = Ctx.getPromotedIntegerType(LTy);
683uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
684LHS = (*doCast)(Solver, LHS, NewTy, NewBitWidth, LTy, LBitWidth);
686LBitWidth = NewBitWidth;
688 if(Ctx.isPromotableIntegerType(RTy)) {
689 QualTypeNewTy = Ctx.getPromotedIntegerType(RTy);
690uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
691RHS = (*doCast)(Solver, RHS, NewTy, NewBitWidth, RTy, RBitWidth);
693RBitWidth = NewBitWidth;
704 intorder = Ctx.getIntegerTypeOrder(LTy, RTy);
705 if(isLSignedTy == isRSignedTy) {
708RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
711LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
714}
else if(order != (isLSignedTy ? 1 : -1)) {
718RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
721LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
724}
else if(LBitWidth != RBitWidth) {
729RHS = (doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
732LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
741Ctx.getCorrespondingUnsignedType(isLSignedTy ? LTy : RTy);
742RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
744LHS = (doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
752 template<
typename T,
T(*doCast)(llvm::SMTSolverRef &Solver,
const T&,
757uint64_t LBitWidth = Ctx.getTypeSize(LTy);
758uint64_t RBitWidth = Ctx.getTypeSize(RTy);
762LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
764LBitWidth = RBitWidth;
767RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
769RBitWidth = LBitWidth;
778 intorder = Ctx.getFloatingTypeOrder(LTy, RTy);
780RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
782}
else if(order == 0) {
783LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
786llvm_unreachable(
"Unsupported floating-point type cast!");
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isComparisonOp() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isVoidPointerType() const
bool isArithmeticType() const
bool isReferenceType() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isObjCObjectPointerType() const
bool isRealFloatingType() const
Floating point categories.
bool isAnyPointerType() const
bool isNullPtrType() const
A record of the "type" of an APSInt, used for conversions.
llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY
Convert and return a new APSInt with the given value, but this type's bit width and signedness.
Template implementation for all binary symbolic expressions.
Represents a symbolic expression involving a binary operator.
BinaryOperator::Opcode getOpcode() const
static llvm::SMTSortRef mkSort(llvm::SMTSolverRef &Solver, const QualType &Ty, unsigned BitWidth)
static llvm::SMTExprRef fromFloatBinOp(llvm::SMTSolverRef &Solver, const llvm::SMTExprRef &LHS, const BinaryOperator::Opcode Op, const llvm::SMTExprRef &RHS)
Construct an SMTSolverRef from a floating-point binary operator.
static QualType getAPSIntType(ASTContext &Ctx, const llvm::APSInt &Int)
static llvm::SMTExprRef getZeroExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const llvm::SMTExprRef &Exp, QualType Ty, bool Assumption)
static void doIntTypeConversion(llvm::SMTSolverRef &Solver, ASTContext &Ctx, T &LHS, QualType <y, T &RHS, QualType &RTy)
static llvm::SMTExprRef getRangeExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym, const llvm::APSInt &From, const llvm::APSInt &To, bool InRange)
static llvm::SMTExprRef fromNBinOp(llvm::SMTSolverRef &Solver, const BinaryOperator::Opcode Op, const std::vector< llvm::SMTExprRef > &ASTs)
Construct an SMTSolverRef from a n-ary binary operator.
static llvm::SMTExprRef getSymExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym, QualType *RetTy, bool *hasComparison)
static llvm::SMTExprRef getExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym, QualType *RetTy=nullptr, bool *hasComparison=nullptr)
static void doTypeConversion(llvm::SMTSolverRef &Solver, ASTContext &Ctx, llvm::SMTExprRef &LHS, llvm::SMTExprRef &RHS, QualType <y, QualType &RTy)
static llvm::SMTExprRef fromFloatSpecialBinOp(llvm::SMTSolverRef &Solver, const llvm::SMTExprRef &LHS, const BinaryOperator::Opcode Op, const llvm::APFloat::fltCategory &RHS)
Construct an SMTSolverRef from a special floating-point binary operator.
static llvm::SMTExprRef fromData(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const SymbolData *Sym)
Construct an SMTSolverRef from a SymbolData.
static void doFloatTypeConversion(llvm::SMTSolverRef &Solver, ASTContext &Ctx, T &LHS, QualType <y, T &RHS, QualType &RTy)
static llvm::SMTExprRef getSymBinExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const BinarySymExpr *BSE, bool *hasComparison, QualType *RetTy)
static llvm::SMTExprRef fromBinOp(llvm::SMTSolverRef &Solver, const llvm::SMTExprRef &LHS, const BinaryOperator::Opcode Op, const llvm::SMTExprRef &RHS, bool isSigned)
Construct an SMTSolverRef from a binary operator.
static llvm::SMTExprRef getCastExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const llvm::SMTExprRef &Exp, QualType FromTy, QualType ToTy)
static llvm::SMTExprRef getBinExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const llvm::SMTExprRef &LHS, QualType LTy, BinaryOperator::Opcode Op, const llvm::SMTExprRef &RHS, QualType RTy, QualType *RetTy)
static std::pair< llvm::APSInt, QualType > fixAPSInt(ASTContext &Ctx, const llvm::APSInt &Int)
static llvm::SMTExprRef fromCast(llvm::SMTSolverRef &Solver, const llvm::SMTExprRef &Exp, QualType ToTy, uint64_t ToBitWidth, QualType FromTy, uint64_t FromBitWidth)
Construct an SMTSolverRef from a QualType FromTy to a QualType ToTy, and their bit widths.
static llvm::APSInt castAPSInt(llvm::SMTSolverRef &Solver, const llvm::APSInt &V, QualType ToTy, uint64_t ToWidth, QualType FromTy, uint64_t FromWidth)
static llvm::SMTExprRef fromFloatUnOp(llvm::SMTSolverRef &Solver, const UnaryOperator::Opcode Op, const llvm::SMTExprRef &Exp)
Constructs an SMTSolverRef from a floating-point unary operator.
static llvm::SMTExprRef fromUnOp(llvm::SMTSolverRef &Solver, const UnaryOperator::Opcode Op, const llvm::SMTExprRef &Exp)
Constructs an SMTSolverRef from an unary operator.
virtual QualType getType() const =0
SymbolID getSymbolID() const
Get a unique identifier for this symbol.
Represents a cast expression.
A symbol representing data which can be stored in a memory location (region).
virtual StringRef getKindStr() const =0
Get a string representation of the kind of the region.
Represents a symbolic expression involving a unary operator.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4