67 SimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
68 ProgramStateManager &stateMgr)
69 : SValBuilder(alloc, context, stateMgr) {}
70 ~SimpleSValBuilder()
override {}
73 NonLoc lhs, NonLoc rhs, QualType resultTy)
override;
75 Loc lhs, Loc rhs, QualType resultTy)
override;
77 Loc lhs, NonLoc rhs, QualType resultTy)
override;
97 const llvm::APSInt &RHS, QualType resultTy);
104 return new SimpleSValBuilder(alloc, context, stateMgr);
111 const unsigned ValueBits =
Value.getSignificantBits();
128SVal SimpleSValBuilder::MakeSymIntVal(
const SymExpr *LHS,
130 const llvm::APSInt &RHS,
132 bool isIdempotent =
false;
142 return makeIntVal(0, resultTy);
150 return UndefinedVal();
158 return UndefinedVal();
160 return makeIntVal(0, resultTy);
174 return makeIntVal(0, resultTy);
175 else if (RHS.isAllOnes())
182 else if (RHS.isAllOnes()) {
183 return nonloc::ConcreteInt(BasicVals.Convert(resultTy, RHS));
192 return evalCast(nonloc::SymbolVal(LHS), resultTy, QualType{});
196 std::optional<APSIntPtr> ConvertedRHS = BasicVals.getValue(RHS);
201 ASTContext &Ctx = getContext();
202 QualType SymbolType = LHS->
getType();
203 uint64_t ValWidth = RHS.getBitWidth();
206 if (ValWidth < TypeWidth) {
208 ConvertedRHS = BasicVals.Convert(SymbolType, RHS);
209 }
else if (ValWidth == TypeWidth) {
214 ConvertedRHS = BasicVals.Convert(SymbolType, RHS);
220 APSIntType resultIntTy = BasicVals.getAPSIntType(resultTy);
222 ConvertedRHS = BasicVals.getValue(-resultIntTy.
convert(RHS));
223 op = (op == BO_Add) ? BO_Sub : BO_Add;
225 ConvertedRHS = BasicVals.Convert(resultTy, RHS);
228 ConvertedRHS = BasicVals.Convert(resultTy, RHS);
230 return makeNonLoc(LHS, op, *ConvertedRHS, resultTy);
242 return !State->assume(*DV,
false);
258 assert(
T->isSignedIntegerOrEnumerationType() &&
259 "This only works with signed integers!");
271 "This only works with signed integers!");
274 return (I <=
Max) && (I >= -
Max);
279 if (
const auto *SymInt = dyn_cast<SymIntExpr>(Sym))
281 return std::make_pair(SymInt->getLHS(),
282 (SymInt->getOpcode() == BO_Add)
283 ? BV.getValue(SymInt->getRHS())
284 : BV.getValue(-SymInt->getRHS()));
287 return std::make_pair(Sym, BV.getValue(0, Sym->
getType()));
302 assert(SymTy == RSym->
getType() &&
303 "Symbols are not of the same type!");
305 "Integers are not of the same type as symbols!");
307 "Integers are not of the same type as symbols!");
315 llvm_unreachable(
"Operation not suitable for unchecked rearrangement!");
325 llvm::APSInt ResultInt;
333 ResultInt = LInt - RInt;
337 ResultInt = RInt - LInt;
341 ResultInt = (Op == BO_Add) ? (LInt + RInt) : (LInt - RInt);
345 ResultInt = -ResultInt;
347 }
else if (ResultInt == 0) {
352 APSIntPtr PersistentResultInt = BV.getValue(ResultInt);
354 ResultSym, ResultOp, PersistentResultInt, ResultTy));
394 if (LSym->
getType() != SingleTy)
401 assert(!SingleTy.
isNull() &&
"We should have figured out the type by now!");
408 if (!RSym || RSym->
getType() != SingleTy)
412 llvm::APSInt LInt, RInt;
425 NonLoc lhs, NonLoc rhs,
427 NonLoc InputLHS = lhs;
428 NonLoc InputRHS = rhs;
432 SVal simplifiedLhs = simplifySVal(state, lhs);
433 SVal simplifiedRhs = simplifySVal(state, rhs);
434 if (
auto simplifiedLhsAsNonLoc = simplifiedLhs.
getAs<NonLoc>())
435 lhs = *simplifiedLhsAsNonLoc;
436 if (
auto simplifiedRhsAsNonLoc = simplifiedRhs.
getAs<NonLoc>())
437 rhs = *simplifiedRhsAsNonLoc;
447 return makeTruthVal(
true, resultTy);
451 return makeTruthVal(
false, resultTy);
455 return makeIntVal(0, resultTy);
456 return evalCast(makeIntVal(0,
false), resultTy,
460 return evalCast(lhs, resultTy, QualType{});
466 return makeSymExprValNN(op, lhs, rhs, resultTy);
467 case nonloc::PointerToMemberKind: {
468 assert(rhs.
getKind() == nonloc::PointerToMemberKind &&
469 "Both SVals should have pointer-to-member-type");
470 auto LPTM = lhs.
castAs<nonloc::PointerToMember>(),
471 RPTM = rhs.
castAs<nonloc::PointerToMember>();
472 auto LPTMD = LPTM.getPTMData(), RPTMD = RPTM.getPTMData();
475 return makeTruthVal(LPTMD == RPTMD, resultTy);
477 return makeTruthVal(LPTMD != RPTMD, resultTy);
482 case nonloc::LocAsIntegerKind: {
483 Loc lhsL = lhs.
castAs<nonloc::LocAsInteger>().getLoc();
485 case nonloc::LocAsIntegerKind:
490 return evalBinOpLL(state, op, lhsL,
491 rhs.
castAs<nonloc::LocAsInteger>().getLoc(),
493 case nonloc::ConcreteIntKind: {
502 llvm::APSInt i = rhs.
castAs<nonloc::ConcreteInt>().getValue();
509 BasicVals.getAPSIntType(lSym->getType()).apply(i);
511 BasicVals.getAPSIntType(Context.
VoidPtrTy).apply(i);
512 return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy);
517 return makeTruthVal(
false, resultTy);
519 return makeTruthVal(
true, resultTy);
522 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
526 case nonloc::ConcreteIntKind: {
527 llvm::APSInt LHSValue = lhs.
castAs<nonloc::ConcreteInt>().getValue();
530 if (
const llvm::APSInt *KnownRHSValue = getConstValue(state, rhs)) {
531 llvm::APSInt RHSValue = *KnownRHSValue;
536 APSIntType CompareType = std::max(APSIntType(LHSValue),
537 APSIntType(RHSValue));
538 CompareType.
apply(LHSValue);
539 CompareType.
apply(RHSValue);
541 APSIntType IntType = BasicVals.getAPSIntType(resultTy);
542 IntType.
apply(LHSValue);
543 IntType.
apply(RHSValue);
546 std::optional<APSIntPtr>
Result =
547 BasicVals.evalAPSInt(op, LHSValue, RHSValue);
549 if (op == BO_Shl || op == BO_Shr) {
561 return UndefinedVal();
564 return nonloc::ConcreteInt(*
Result);
589 if (LHSValue.isAllOnes() && LHSValue.isSigned())
590 return evalCast(lhs, resultTy, QualType{});
595 return evalCast(lhs, resultTy, QualType{});
596 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
602 return makeZeroVal(resultTy);
605 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
608 case nonloc::SymbolValKind: {
613 if (
const SymIntExpr *symIntExpr = dyn_cast<SymIntExpr>(Sym)) {
627 llvm_unreachable(
"Logical operators handled by branching logic.");
640 llvm_unreachable(
"'=' and ',' operators handled by ExprEngine.");
643 llvm_unreachable(
"Pointer arithmetic not handled here.");
651 resultTy == getConditionType());
652 assert(symIntExpr->getType()->isBooleanType() ||
653 getContext().hasSameUnqualifiedType(symIntExpr->getType(),
654 getConditionType()));
657 return makeNonLoc(symIntExpr->getLHS(), opc,
658 symIntExpr->getRHS(), resultTy);
663 if (
const llvm::APSInt *RHSValue = getConstValue(state, rhs)) {
676 APSIntType IntType = BasicVals.getAPSIntType(resultTy);
677 const llvm::APSInt &first = IntType.
convert(symIntExpr->getRHS());
678 const llvm::APSInt &second = IntType.
convert(*RHSValue);
687 std::optional<APSIntPtr> newRHS;
689 newRHS = BasicVals.evalAPSInt(BO_Add, first, second);
690 }
else if (first >= second) {
691 newRHS = BasicVals.evalAPSInt(BO_Sub, first, second);
694 newRHS = BasicVals.evalAPSInt(BO_Sub, second, first);
697 assert(newRHS &&
"Invalid operation despite common type!");
698 rhs = nonloc::ConcreteInt(*newRHS);
699 lhs = nonloc::SymbolVal(symIntExpr->getLHS());
705 return MakeSymIntVal(symIntExpr, op, *RHSValue, resultTy);
710 if (
const llvm::APSInt *RHSValue = getConstValue(state, rhs))
711 return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
713 if (std::optional<NonLoc>
V =
tryRearrange(state, op, lhs, rhs, resultTy))
717 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
727 SimpleSValBuilder &SVB) {
750 return SVB.makeTruthVal(
false, resultTy);
752 return SVB.makeTruthVal(
true, resultTy);
758 bool leftFirst = (op == BO_LT || op == BO_LE);
759 for (
const auto *I : RD->
fields()) {
761 return SVB.makeTruthVal(leftFirst, resultTy);
763 return SVB.makeTruthVal(!leftFirst, resultTy);
766 llvm_unreachable(
"Fields not found in parent record's definition");
779 ASTContext &Ctx = State->getStateManager().getContext();
780 uint64_t RhsBitwidth =
782 uint64_t LhsBitwidth =
784 if (RhsBitwidth && LhsBitwidth && (LhsLoc.
getKind() == RhsLoc.
getKind())) {
785 assert(RhsBitwidth == LhsBitwidth &&
786 "RhsLoc and LhsLoc bitwidth must be same!");
816 llvm_unreachable(
"Unimplemented operation for two identical values");
818 return makeZeroVal(resultTy);
822 return makeTruthVal(
true, resultTy);
826 return makeTruthVal(
false, resultTy);
832 llvm_unreachable(
"Ordering not implemented for this Loc.");
834 case loc::GotoLabelKind:
841 return evalCast(lhs, resultTy, QualType{});
845 return makeTruthVal(
false, resultTy);
849 return makeTruthVal(
true, resultTy);
859 case loc::ConcreteIntKind: {
860 auto L = lhs.
castAs<loc::ConcreteInt>();
869 return makeNonLoc(L.getValue(), op, rSym, resultTy);
872 return makeNonLoc(rSym, op, L.getValue(), resultTy);
876 if (std::optional<loc::ConcreteInt> rInt = rhs.
getAs<loc::ConcreteInt>()) {
879 if (std::optional<APSIntPtr> ResultInt =
880 BasicVals.evalAPSInt(op, L.getValue(), rInt->getValue()))
881 return evalCast(nonloc::ConcreteInt(*ResultInt), resultTy, QualType{});
897 return makeTruthVal(
false, resultTy);
901 return makeTruthVal(
true, resultTy);
909 case loc::MemRegionValKind: {
910 if (std::optional<loc::ConcreteInt> rInt = rhs.
getAs<loc::ConcreteInt>()) {
915 return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
922 if (rInt->isZeroConstant()) {
924 return evalCast(lhs, resultTy, QualType{});
927 QualType boolType = getContext().BoolTy;
928 NonLoc l = evalCast(lhs, boolType, QualType{}).castAs<NonLoc>();
929 NonLoc r = makeTruthVal(
false, boolType).castAs<NonLoc>();
930 return evalBinOpNN(state, op, l, r, resultTy);
940 assert(LeftMR &&
"MemRegionValKind SVal doesn't have a region!");
953 const MemSpaceRegion *UnknownMS = MemMgr.getUnknownRegion();
958 if (LeftMS != RightMS &&
959 ((LeftMS != UnknownMS && RightMS != UnknownMS) ||
965 return makeTruthVal(
false, resultTy);
967 return makeTruthVal(
true, resultTy);
981 if (LeftBase != RightBase &&
988 return makeTruthVal(
false, resultTy);
990 return makeTruthVal(
true, resultTy);
995 const ElementRegion *RightER = dyn_cast<ElementRegion>(RightMR);
996 const ElementRegion *LeftER = dyn_cast<ElementRegion>(LeftMR);
997 if (RightER && LeftER) {
1006 SVal LeftIndexVal = LeftER->
getIndex();
1007 std::optional<NonLoc> LeftIndex = LeftIndexVal.
getAs<NonLoc>();
1009 return UnknownVal();
1010 LeftIndexVal = evalCast(*LeftIndex, ArrayIndexTy, QualType{});
1011 LeftIndex = LeftIndexVal.
getAs<NonLoc>();
1013 return UnknownVal();
1016 SVal RightIndexVal = RightER->
getIndex();
1017 std::optional<NonLoc> RightIndex = RightIndexVal.
getAs<NonLoc>();
1019 return UnknownVal();
1020 RightIndexVal = evalCast(*RightIndex, ArrayIndexTy, QualType{});
1021 RightIndex = RightIndexVal.
getAs<NonLoc>();
1023 return UnknownVal();
1027 return evalBinOpNN(state, op, *LeftIndex, *RightIndex, resultTy);
1032 const FieldRegion *RightFR = dyn_cast<FieldRegion>(RightMR);
1033 const FieldRegion *LeftFR = dyn_cast<FieldRegion>(LeftMR);
1034 if (RightFR && LeftFR) {
1043 RegionOffset RightOffset = RightMR->
getAsOffset();
1045 if (LeftOffset.
getRegion() !=
nullptr &&
1053 return UnknownVal();
1055 return makeTruthVal(left < right, resultTy);
1057 return makeTruthVal(left > right, resultTy);
1059 return makeTruthVal(left <= right, resultTy);
1061 return makeTruthVal(left >= right, resultTy);
1063 return makeTruthVal(left == right, resultTy);
1065 return makeTruthVal(left != right, resultTy);
1073 if (LHSSym && RHSSym)
1074 return makeNonLoc(LHSSym, op, RHSSym, resultTy);
1077 return UnknownVal();
1084 NonLoc rhs, QualType resultTy) {
1085 if (op >= BO_PtrMemD && op <= BO_PtrMemI) {
1086 if (
auto PTMSV = rhs.
getAs<nonloc::PointerToMember>()) {
1087 if (PTMSV->isNullMemberPointer())
1088 return UndefinedVal();
1090 auto getFieldLValue = [&](
const auto *FD) -> SVal {
1093 for (
const auto &I : *PTMSV)
1094 Result = StateMgr.getStoreManager().evalDerivedToBase(
1095 Result, I->getType(), I->isVirtual());
1097 return state->getLValue(FD,
Result);
1100 if (
const auto *FD = PTMSV->getDeclAs<FieldDecl>()) {
1101 return getFieldLValue(FD);
1103 if (
const auto *FD = PTMSV->getDeclAs<IndirectFieldDecl>()) {
1104 return getFieldLValue(FD);
1112 "arguments to comparison ops must be of the same type");
1125 if (std::optional<nonloc::ConcreteInt> rhsInt =
1126 rhs.
getAs<nonloc::ConcreteInt>()) {
1127 if (std::optional<loc::ConcreteInt> lhsInt =
1128 lhs.
getAs<loc::ConcreteInt>()) {
1129 const llvm::APSInt &leftI = lhsInt->getValue();
1130 assert(leftI.isUnsigned());
1131 llvm::APSInt rightI(rhsInt->getValue(),
true);
1135 rightI = rightI.extOrTrunc(leftI.getBitWidth());
1138 llvm::APSInt Multiplicand(rightI.getBitWidth(),
true);
1140 Multiplicand = getContext().getTypeSizeInChars(pointeeType).getQuantity();
1141 rightI *= Multiplicand;
1146 rightI = leftI + rightI;
1149 rightI = leftI - rightI;
1152 llvm_unreachable(
"Invalid pointer arithmetic operation");
1154 return loc::ConcreteInt(getBasicValueFactory().getValue(rightI));
1159 if (
const MemRegion *region = lhs.
getAsRegion()) {
1160 rhs = convertToArrayIndex(rhs).
castAs<NonLoc>();
1161 SVal index = UnknownVal();
1162 const SubRegion *superR =
nullptr;
1165 QualType elementType;
1167 if (
const ElementRegion *elemReg = dyn_cast<ElementRegion>(region)) {
1168 assert(op == BO_Add || op == BO_Sub);
1169 index = evalBinOpNN(state, op, elemReg->getIndex(), rhs,
1170 getArrayIndexType());
1172 elementType = elemReg->getElementType();
1175 assert(op == BO_Add || op == BO_Sub);
1176 index = (op == BO_Add) ? rhs : evalMinus(rhs);
1190 elementType = getContext().CharTy;
1192 if (std::optional<NonLoc> indexV = index.getAs<NonLoc>()) {
1193 return loc::MemRegionVal(MemMgr.getElementRegion(elementType, *indexV,
1194 superR, getContext()));
1197 return UnknownVal();
1200const llvm::APSInt *SimpleSValBuilder::getConstValue(
ProgramStateRef state,
1206 return state->getConstraintManager().getSymVal(state, Sym);
1211const llvm::APSInt *SimpleSValBuilder::getConcreteValue(SVal
V) {
1212 if (std::optional<loc::ConcreteInt>
X =
V.getAs<loc::ConcreteInt>())
1213 return X->getValue().get();
1215 if (std::optional<nonloc::ConcreteInt>
X =
V.getAs<nonloc::ConcreteInt>())
1216 return X->getValue().get();
1221const llvm::APSInt *SimpleSValBuilder::getKnownValue(
ProgramStateRef state,
1223 return getConstValue(state, simplifySVal(state,
V));
1226const llvm::APSInt *SimpleSValBuilder::getMinValue(
ProgramStateRef state,
1228 V = simplifySVal(state,
V);
1234 return state->getConstraintManager().getSymMinVal(state, Sym);
1239const llvm::APSInt *SimpleSValBuilder::getMaxValue(
ProgramStateRef state,
1241 V = simplifySVal(state,
V);
1247 return state->getConstraintManager().getSymMaxVal(state, Sym);
1252SVal SimpleSValBuilder::simplifyUntilFixpoint(
ProgramStateRef State, SVal Val) {
1253 SVal SimplifiedVal = simplifySValOnce(State, Val);
1254 while (SimplifiedVal != Val) {
1255 Val = SimplifiedVal;
1256 SimplifiedVal = simplifySValOnce(State, Val);
1258 return SimplifiedVal;
1262 return simplifyUntilFixpoint(State,
V);
1270 class Simplifier :
public FullSValVisitor<Simplifier, SVal> {
1278 llvm::DenseMap<SymbolRef, SVal> Cached;
1280 static bool isUnchanged(
SymbolRef Sym, SVal Val) {
1296 const llvm::APSInt *
Const =
1297 State->getConstraintManager().getSymVal(State, Sym);
1301 return UndefinedVal();
1313 : State(State), SVB(State->getStateManager().getSValBuilder()) {}
1315 SVal VisitSymbolData(
const SymbolData *S) {
1317 if (
const llvm::APSInt *I =
1318 State->getConstraintManager().getSymVal(State, S))
1325 auto I = Cached.find(S);
1326 if (I != Cached.end())
1329 SVal LHS = getConstOrVisit(S->
getLHS());
1330 if (isUnchanged(S->
getLHS(), LHS))
1357 auto I = Cached.find(S);
1358 if (I != Cached.end())
1361 SVal RHS = getConstOrVisit(S->
getRHS());
1362 if (isUnchanged(S->
getRHS(), RHS))
1371 auto I = Cached.find(S);
1372 if (I != Cached.end())
1383 SVal LHS = getConstOrVisit(S->
getLHS());
1384 SVal RHS = getConstOrVisit(S->
getRHS());
1386 if (isUnchanged(S->
getLHS(), LHS) && isUnchanged(S->
getRHS(), RHS))
1393 SVal VisitSymbolCast(
const SymbolCast *S) {
1394 auto I = Cached.find(S);
1395 if (I != Cached.end())
1398 SVal OpVal = getConstOrVisit(OpSym);
1399 if (isUnchanged(OpSym, OpVal))
1405 SVal VisitUnarySymExpr(
const UnarySymExpr *S) {
1406 auto I = Cached.find(S);
1407 if (I != Cached.end())
1417 SVal VisitSymExpr(
SymbolRef S) {
return nonloc::SymbolVal(S); }
1419 SVal VisitMemRegion(
const MemRegion *R) {
return loc::MemRegionVal(R); }
1421 SVal VisitSymbolVal(nonloc::SymbolVal
V) {
1424 return Visit(
V.getSymbol());
1427 SVal VisitSVal(SVal
V) {
return V; }
1430 SVal SimplifiedV = Simplifier(State).Visit(
V);
static std::optional< int64_t > getConcreteValue(NonLoc SV)
mlir::Value getConst(mlir::OpBuilder &bld, mlir::Location loc, mlir::Type typ, unsigned val)
static bool isInRelation(BinaryOperator::Opcode Rel, SymbolRef Sym, llvm::APSInt Bound, ProgramStateRef State)
static NonLoc doRearrangeUnchecked(ProgramStateRef State, BinaryOperator::Opcode Op, SymbolRef LSym, llvm::APSInt LInt, SymbolRef RSym, llvm::APSInt RInt)
static bool isNegationValuePreserving(const llvm::APSInt &Value, APSIntType ResultType)
static std::optional< NonLoc > tryRearrange(ProgramStateRef State, BinaryOperator::Opcode Op, NonLoc Lhs, NonLoc Rhs, QualType ResultTy)
static bool shouldRearrange(ProgramStateRef State, BinaryOperator::Opcode Op, SymbolRef Sym, llvm::APSInt Int, QualType Ty)
static SVal evalBinOpFieldRegionFieldRegion(const FieldRegion *LeftFR, const FieldRegion *RightFR, BinaryOperator::Opcode op, QualType resultTy, SimpleSValBuilder &SVB)
static bool isWithinConstantOverflowBounds(SymbolRef Sym, ProgramStateRef State)
static std::pair< SymbolRef, APSIntPtr > decomposeSymbol(SymbolRef Sym, BasicValueFactory &BV)
static void assertEqualBitWidths(ProgramStateRef State, Loc RhsLoc, Loc LhsLoc)
static std::optional< int64_t > getKnownValue(ProgramStateRef State, SVal V)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
static bool isComparisonOp(Opcode Opc)
bool isComparisonOp() const
static Opcode negateComparisonOp(Opcode Opc)
static Opcode reverseComparisonOp(Opcode Opc)
bool isAdditiveOp() const
static bool isAdditiveOp(Opcode Opc)
BinaryOperatorKind Opcode
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Represents a struct/union/class.
field_range fields() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isAnyPointerType() const
A safe wrapper around APSInt objects allocated and owned by BasicValueFactory.
A record of the "type" of an APSInt, used for conversions.
uint32_t getBitWidth() const
llvm::APSInt getMaxValue() const LLVM_READONLY
Returns the maximum value for this type.
void apply(llvm::APSInt &Value) const
Convert a given APSInt, in place, to match this type.
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.
llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY
APSIntType getAPSIntType(QualType T) const
Returns the type of the APSInt used to store values of the given QualType.
QualType getType() const override
BinaryOperator::Opcode getOpcode() const
QualType getElementType() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const FieldDecl * getDecl() const override
static bool isLocType(QualType T)
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace(ProgramStateRef State) const
Returns the most specific memory space for this memory region in the given ProgramStateRef.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
SValBuilder & getSValBuilder()
bool hasSymbolicOffset() const
const MemRegion * getRegion() const
It might return null.
int64_t getOffset() const
BasicValueFactory & getBasicValueFactory()
ProgramStateManager & getStateManager()
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
loc::MemRegionVal makeLoc(SymbolRef sym)
virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy)=0
Create a new value which represents a binary expression with two non- location operands.
DefinedSVal makeSymbolVal(SymbolRef Sym)
Make an SVal that represents the given symbol.
SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy)
Cast a given SVal to another SVal using given QualType's.
const AnalyzerOptions & getAnalyzerOptions() const
QualType getConditionType() const
SVal evalUnaryOp(ProgramStateRef state, UnaryOperator::Opcode opc, SVal operand, QualType type)
SymbolManager & getSymbolManager()
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
loc::ConcreteInt makeIntLocVal(const llvm::APSInt &integer)
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
bool isZeroConstant() const
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
QualType getType(const ASTContext &) const
Try to get a reasonable type for the given value.
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
virtual QualType getType() const =0
QualType getType() const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const SymExpr * getOperand() const
const SymExprT * acquire(Args &&...args)
Create or retrieve a SymExpr of type SymExprT for the given arguments.
QualType getType() const override
UnaryOperator::Opcode getOpcode() const
const SymExpr * getOperand() const
Value representing integer constant.
Represents symbolic expression that isn't a location.
SValBuilder * createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
BinarySymExprImpl< APSIntPtr, const SymExpr *, SymExpr::Kind::IntSymExprKind > IntSymExpr
Represents a symbolic expression like 3 - 'x'.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
BinarySymExprImpl< const SymExpr *, const SymExpr *, SymExpr::Kind::SymSymExprKind > SymSymExpr
Represents a symbolic expression like 'x' + 'y'.
BinarySymExprImpl< const SymExpr *, APSIntPtr, SymExpr::Kind::SymIntExprKind > SymIntExpr
Represents a symbolic expression like 'x' + 3.
bool Const(InterpState &S, CodePtr OpPC, const T &Arg)
bool Ret(InterpState &S, CodePtr &PC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Result
The result type of a method or function.
const FunctionProtoType * T
U cast(CodeGen::Address addr)