18 using namespace clang;
29 SimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
ASTContext &context,
32 ~SimpleSValBuilder()
override {}
48 const llvm::APSInt &RHS,
QualType resultTy);
55 return new SimpleSValBuilder(alloc, context, stateMgr);
78 if (castSize == LI->getNumBits())
80 return makeLocAsInteger(LI->getLoc(), castSize);
92 if (haveSameType(T, castTy))
96 return makeNonLoc(se, T, castTy);
107 return makeTruthVal(b, castTy);
116 BasicVals.getAPSIntType(castTy).apply(i);
119 return makeIntLocVal(i);
121 return makeIntVal(i);
147 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FTR->getDecl()))
162 return makeTruthVal(
true, castTy);
170 return makeLocAsInteger(val, BitWidth);
173 BasicVals.getAPSIntType(castTy).apply(i);
174 return makeIntVal(i);
187 SVal SimpleSValBuilder::evalMinus(
NonLoc val) {
209 SVal SimpleSValBuilder::MakeSymIntVal(
const SymExpr *LHS,
211 const llvm::APSInt &RHS,
213 bool isIdempotent =
false;
223 return makeIntVal(0, resultTy);
241 return makeIntVal(0, resultTy);
255 return makeIntVal(0, resultTy);
256 else if (RHS.isAllOnesValue())
263 else if (RHS.isAllOnesValue()) {
264 const llvm::APSInt &
Result = BasicVals.Convert(resultTy, RHS);
278 const llvm::APSInt *ConvertedRHS = &RHS;
285 uint64_t ValWidth = RHS.getBitWidth();
288 if (ValWidth < TypeWidth) {
290 ConvertedRHS = &BasicVals.Convert(SymbolType, RHS);
291 }
else if (ValWidth == TypeWidth) {
296 ConvertedRHS = &BasicVals.Convert(SymbolType, RHS);
299 ConvertedRHS = &BasicVals.Convert(resultTy, RHS);
301 return makeNonLoc(LHS, op, *ConvertedRHS, resultTy);
319 return makeTruthVal(
true, resultTy);
323 return makeTruthVal(
false, resultTy);
327 return makeIntVal(0, resultTy);
328 return evalCastFromNonLoc(makeIntVal(0,
false), resultTy);
331 return evalCastFromNonLoc(lhs, resultTy);
337 return makeSymExprValNN(state, op, lhs, rhs, resultTy);
342 return evalBinOpLL(state, op, lhsL,
349 return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy);
354 return makeTruthVal(
false, resultTy);
356 return makeTruthVal(
true, resultTy);
359 return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
367 if (
const llvm::APSInt *KnownRHSValue = getKnownValue(state, rhs)) {
368 llvm::APSInt RHSValue = *KnownRHSValue;
375 CompareType.
apply(LHSValue);
376 CompareType.
apply(RHSValue);
378 APSIntType IntType = BasicVals.getAPSIntType(resultTy);
379 IntType.
apply(LHSValue);
380 IntType.
apply(RHSValue);
383 const llvm::APSInt *
Result =
384 BasicVals.evalAPSInt(op, LHSValue, RHSValue);
413 if (LHSValue.isAllOnesValue() && LHSValue.isSigned())
414 return evalCastFromNonLoc(lhs, resultTy);
419 return evalCastFromNonLoc(lhs, resultTy);
420 return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
422 return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
430 if (
const SymIntExpr *symIntExpr = dyn_cast<SymIntExpr>(Sym)) {
444 llvm_unreachable(
"Logical operators handled by branching logic.");
457 llvm_unreachable(
"'=' and ',' operators handled by ExprEngine.");
460 llvm_unreachable(
"Pointer arithmetic not handled here.");
468 resultTy == getConditionType());
469 assert(symIntExpr->getType()->isBooleanType() ||
470 getContext().hasSameUnqualifiedType(symIntExpr->getType(),
471 getConditionType()));
474 return makeNonLoc(symIntExpr->getLHS(), opc,
475 symIntExpr->getRHS(), resultTy);
480 if (
const llvm::APSInt *RHSValue = getKnownValue(state, rhs)) {
493 APSIntType IntType = BasicVals.getAPSIntType(resultTy);
494 const llvm::APSInt &first = IntType.
convert(symIntExpr->getRHS());
495 const llvm::APSInt &second = IntType.
convert(*RHSValue);
497 const llvm::APSInt *newRHS;
499 newRHS = BasicVals.evalAPSInt(
BO_Add, first, second);
501 newRHS = BasicVals.evalAPSInt(
BO_Sub, first, second);
503 assert(newRHS &&
"Invalid operation despite common type!");
512 return MakeSymIntVal(symIntExpr, op, *RHSValue, resultTy);
520 if (
const llvm::APSInt *Constant = CMgr.
getSymVal(state, Sym)) {
526 if (
const llvm::APSInt *RHSValue = getKnownValue(state, rhs))
527 return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
530 return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
540 SimpleSValBuilder &SVB) {
563 return SVB.makeTruthVal(
false, resultTy);
565 return SVB.makeTruthVal(
true, resultTy);
571 bool leftFirst = (op ==
BO_LT || op ==
BO_LE);
572 for (
const auto *I : RD->
fields()) {
574 return SVB.makeTruthVal(leftFirst, resultTy);
576 return SVB.makeTruthVal(!leftFirst, resultTy);
579 llvm_unreachable(
"Fields not found in parent record's definition");
600 llvm_unreachable(
"Unimplemented operation for two identical values");
602 return makeZeroVal(resultTy);
606 return makeTruthVal(
true, resultTy);
610 return makeTruthVal(
false, resultTy);
616 llvm_unreachable(
"Ordering not implemented for this Loc.");
625 return evalCastFromLoc(lhs, resultTy);
629 return makeTruthVal(
false, resultTy);
633 return makeTruthVal(
true, resultTy);
654 return makeNonLoc(rSym, op, lVal, resultTy);
662 return evalCastFromNonLoc(*Result, resultTy);
664 assert(!ResultVal.
getAs<
Loc>() &&
"Loc-Loc ops should not produce Locs");
680 return makeTruthVal(
false, resultTy);
684 return makeTruthVal(
true, resultTy);
697 return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
703 if (rInt->isZeroConstant()) {
705 return evalCastFromLoc(lhs, resultTy);
708 QualType boolType = getContext().BoolTy;
711 return evalBinOpNN(state, op, l, r, resultTy);
721 assert(LeftMR &&
"MemRegionKind SVal doesn't have a region!");
739 if (LeftMS != RightMS &&
740 ((LeftMS != UnknownMS && RightMS != UnknownMS) ||
741 (isa<StackSpaceRegion>(LeftMS) || isa<StackSpaceRegion>(RightMS)))) {
746 return makeTruthVal(
false, resultTy);
748 return makeTruthVal(
true, resultTy);
756 if (LeftBase != RightBase &&
757 ((!isa<SymbolicRegion>(LeftBase) && !isa<SymbolicRegion>(RightBase)) ||
758 (isa<HeapSpaceRegion>(LeftMS) || isa<HeapSpaceRegion>(RightMS))) ){
763 return makeTruthVal(
false, resultTy);
765 return makeTruthVal(
true, resultTy);
772 if (RightER && LeftER) {
781 SVal LeftIndexVal = LeftER->getIndex();
785 LeftIndexVal = evalCastFromNonLoc(*LeftIndex, ArrayIndexTy);
795 RightIndexVal = evalCastFromNonLoc(*RightIndex, ArrayIndexTy);
802 return evalBinOpNN(state, op, *LeftIndex, *RightIndex, resultTy);
809 if (RightFR && LeftFR) {
830 return makeTruthVal(left < right, resultTy);
832 return makeTruthVal(left > right, resultTy);
834 return makeTruthVal(left <= right, resultTy);
836 return makeTruthVal(left >= right, resultTy);
838 return makeTruthVal(left == right, resultTy);
840 return makeTruthVal(left != right, resultTy);
848 if (LHSSym && RHSSym)
849 return makeNonLoc(LHSSym, op, RHSSym, resultTy);
861 "arguments to comparison ops must be of the same type");
872 const llvm::APSInt &leftI = lhsInt->getValue();
873 assert(leftI.isUnsigned());
874 llvm::APSInt rightI(rhsInt->getValue(),
true);
878 rightI = rightI.extOrTrunc(leftI.getBitWidth());
881 llvm::APSInt Multiplicand(rightI.getBitWidth(),
true);
882 rightI *= Multiplicand;
887 rightI = leftI + rightI;
890 rightI = leftI - rightI;
893 llvm_unreachable(
"Invalid pointer arithmetic operation");
906 if (
const ElementRegion *elemReg = dyn_cast<ElementRegion>(region)) {
908 index = evalBinOpNN(state, op, elemReg->getIndex(), rhs,
909 getArrayIndexType());
910 superR = elemReg->getSuperRegion();
911 elementType = elemReg->getElementType();
913 else if (isa<SubRegion>(region)) {
922 superR, getContext()));
928 const llvm::APSInt *SimpleSValBuilder::getKnownValue(
ProgramStateRef state,
934 return &X->getValue();
937 return &X->getValue();
940 return state->getConstraintManager().getSymVal(state, Sym);
MemRegion - The root abstract class for all memory regions.
SValBuilder * createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
bool isBooleanType() const
Value representing integer constant.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QualType getElementType() const
const MemRegion * getBaseRegion() const
bool isZeroConstant() const
Symbolic value. These values used to capture symbolic execution of the program.
bool isComparisonOp() const
const MemSpaceRegion * getMemorySpace() const
static Opcode reverseComparisonOp(Opcode Opc)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isReferenceType() const
bool isAnyPointerType() const
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef. Otherwise return 0...
static bool isLocType(QualType T)
const SymbolicRegion * getSymbolicBase() const
If this is a symbolic region, returns the region. Otherwise, goes up the base chain looking for the f...
field_range fields() const
bool isUnknownOrUndef() const
A record of the "type" of an APSInt, used for conversions.
Represents a symbolic expression like 'x' + 3.
Represent a region's offset within the top level base region.
FunctionTextRegion - A region that represents code texts of function.
virtual QualType getType() const =0
const MemRegion * getSuperRegion() const
static Opcode negateComparisonOp(Opcode Opc)
QualType getPointeeType() const
bool isSignedIntegerOrEnumerationType() const
bool hasSymbolicOffset() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
static SVal getValue(SVal val, SValBuilder &svalBuilder)
The result type of a method or function.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
const FieldDecl * getDecl() const
bool isAdditiveOp() const
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY
unsigned getSubKind() const
void apply(llvm::APSInt &Value) const
Convert a given APSInt, in place, to match this type.
Represents symbolic expression.
const MemRegion * getAsRegion() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
int64_t getOffset() const
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef. Otherwise, return 0.
ElementRegin is used to represent both array elements and casts.
const MemRegion * getRegion() const
virtual const llvm::APSInt * getSymVal(ProgramStateRef state, SymbolRef sym) const
If a symbol is perfectly constrained to a constant, attempt to return the concrete value...
const SymExpr * getAsSymbolicExpression() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
const RecordDecl * getParent() const
static SVal evalBinOpFieldRegionFieldRegion(const FieldRegion *LeftFR, const FieldRegion *RightFR, BinaryOperator::Opcode op, QualType resultTy, SimpleSValBuilder &SVB)