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()));
315 if (ResultTy != CommonTy)
328 if (!RSym || RSym->
getType() != CommonTy)
332 llvm::APSInt LInt, RInt;
343 auto InBounds = [State](
auto...
X) {
363 llvm::APSInt ResultInt;
369 ResultSV = MakeSymExprVal(RSym, BO_Sub, LSym);
371 ResultInt = LInt - RInt;
373 ResultSV = MakeSymExprVal(LSym, BO_Sub, RSym);
375 ResultInt = RInt - LInt;
378 ResultSV = MakeSymExprVal(LSym, Op, RSym);
379 ResultInt = (Op == BO_Add) ? (LInt + RInt) : (LInt - RInt);
383 ResultInt = -ResultInt;
385 }
else if (ResultInt == 0) {
400 NonLoc lhs, NonLoc rhs,
402 NonLoc InputLHS = lhs;
403 NonLoc InputRHS = rhs;
407 SVal simplifiedLhs = simplifySVal(state, lhs);
408 SVal simplifiedRhs = simplifySVal(state, rhs);
409 if (
auto simplifiedLhsAsNonLoc = simplifiedLhs.
getAs<NonLoc>())
410 lhs = *simplifiedLhsAsNonLoc;
411 if (
auto simplifiedRhsAsNonLoc = simplifiedRhs.
getAs<NonLoc>())
412 rhs = *simplifiedRhsAsNonLoc;
422 return makeTruthVal(
true, resultTy);
426 return makeTruthVal(
false, resultTy);
430 return makeIntVal(0, resultTy);
431 return evalCast(makeIntVal(0,
false), resultTy,
435 return evalCast(lhs, resultTy, QualType{});
441 return makeSymExprValNN(op, lhs, rhs, resultTy);
442 case nonloc::PointerToMemberKind: {
443 assert(rhs.
getKind() == nonloc::PointerToMemberKind &&
444 "Both SVals should have pointer-to-member-type");
445 auto LPTM = lhs.
castAs<nonloc::PointerToMember>(),
446 RPTM = rhs.
castAs<nonloc::PointerToMember>();
447 auto LPTMD = LPTM.getPTMData(), RPTMD = RPTM.getPTMData();
450 return makeTruthVal(LPTMD == RPTMD, resultTy);
452 return makeTruthVal(LPTMD != RPTMD, resultTy);
457 case nonloc::LocAsIntegerKind: {
458 Loc lhsL = lhs.
castAs<nonloc::LocAsInteger>().getLoc();
460 case nonloc::LocAsIntegerKind:
465 return evalBinOpLL(state, op, lhsL,
466 rhs.
castAs<nonloc::LocAsInteger>().getLoc(),
468 case nonloc::ConcreteIntKind: {
477 llvm::APSInt i = rhs.
castAs<nonloc::ConcreteInt>().getValue();
484 BasicVals.getAPSIntType(lSym->getType()).apply(i);
486 BasicVals.getAPSIntType(Context.
VoidPtrTy).apply(i);
487 return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy);
492 return makeTruthVal(
false, resultTy);
494 return makeTruthVal(
true, resultTy);
497 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
501 case nonloc::ConcreteIntKind: {
502 llvm::APSInt LHSValue = lhs.
castAs<nonloc::ConcreteInt>().getValue();
505 if (
const llvm::APSInt *KnownRHSValue = getConstValue(state, rhs)) {
506 llvm::APSInt RHSValue = *KnownRHSValue;
511 APSIntType CompareType = std::max(APSIntType(LHSValue),
512 APSIntType(RHSValue));
513 CompareType.
apply(LHSValue);
514 CompareType.
apply(RHSValue);
516 APSIntType IntType = BasicVals.getAPSIntType(resultTy);
517 IntType.
apply(LHSValue);
518 IntType.
apply(RHSValue);
521 std::optional<APSIntPtr>
Result =
522 BasicVals.evalAPSInt(op, LHSValue, RHSValue);
524 if (op == BO_Shl || op == BO_Shr) {
536 return UndefinedVal();
539 return nonloc::ConcreteInt(*
Result);
564 if (LHSValue.isAllOnes() && LHSValue.isSigned())
565 return evalCast(lhs, resultTy, QualType{});
570 return evalCast(lhs, resultTy, QualType{});
571 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
577 return makeZeroVal(resultTy);
580 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
583 case nonloc::SymbolValKind: {
588 if (
const SymIntExpr *symIntExpr = dyn_cast<SymIntExpr>(Sym)) {
602 llvm_unreachable(
"Logical operators handled by branching logic.");
615 llvm_unreachable(
"'=' and ',' operators handled by ExprEngine.");
618 llvm_unreachable(
"Pointer arithmetic not handled here.");
626 resultTy == getConditionType());
627 assert(symIntExpr->getType()->isBooleanType() ||
628 getContext().hasSameUnqualifiedType(symIntExpr->getType(),
629 getConditionType()));
632 return makeNonLoc(symIntExpr->getLHS(), opc,
633 symIntExpr->getRHS(), resultTy);
638 if (
const llvm::APSInt *RHSValue = getConstValue(state, rhs)) {
651 APSIntType IntType = BasicVals.getAPSIntType(resultTy);
652 const llvm::APSInt &first = IntType.
convert(symIntExpr->getRHS());
653 const llvm::APSInt &second = IntType.
convert(*RHSValue);
662 std::optional<APSIntPtr> newRHS;
664 newRHS = BasicVals.evalAPSInt(BO_Add, first, second);
665 }
else if (first >= second) {
666 newRHS = BasicVals.evalAPSInt(BO_Sub, first, second);
669 newRHS = BasicVals.evalAPSInt(BO_Sub, second, first);
672 assert(newRHS &&
"Invalid operation despite common type!");
673 rhs = nonloc::ConcreteInt(*newRHS);
674 lhs = nonloc::SymbolVal(symIntExpr->getLHS());
680 return MakeSymIntVal(symIntExpr, op, *RHSValue, resultTy);
685 if (
const llvm::APSInt *RHSValue = getConstValue(state, rhs))
686 return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
688 if (std::optional<NonLoc>
V =
tryRearrange(state, op, lhs, rhs, resultTy))
692 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
702 SimpleSValBuilder &SVB) {
725 return SVB.makeTruthVal(
false, resultTy);
727 return SVB.makeTruthVal(
true, resultTy);
733 bool leftFirst = (op == BO_LT || op == BO_LE);
734 for (
const auto *I : RD->
fields()) {
736 return SVB.makeTruthVal(leftFirst, resultTy);
738 return SVB.makeTruthVal(!leftFirst, resultTy);
741 llvm_unreachable(
"Fields not found in parent record's definition");
754 ASTContext &Ctx = State->getStateManager().getContext();
755 uint64_t RhsBitwidth =
757 uint64_t LhsBitwidth =
759 if (RhsBitwidth && LhsBitwidth && (LhsLoc.
getKind() == RhsLoc.
getKind())) {
760 assert(RhsBitwidth == LhsBitwidth &&
761 "RhsLoc and LhsLoc bitwidth must be same!");
791 llvm_unreachable(
"Unimplemented operation for two identical values");
793 return makeZeroVal(resultTy);
797 return makeTruthVal(
true, resultTy);
801 return makeTruthVal(
false, resultTy);
807 llvm_unreachable(
"Ordering not implemented for this Loc.");
809 case loc::GotoLabelKind:
816 return evalCast(lhs, resultTy, QualType{});
820 return makeTruthVal(
false, resultTy);
824 return makeTruthVal(
true, resultTy);
834 case loc::ConcreteIntKind: {
835 auto L = lhs.
castAs<loc::ConcreteInt>();
844 return makeNonLoc(L.getValue(), op, rSym, resultTy);
847 return makeNonLoc(rSym, op, L.getValue(), resultTy);
851 if (std::optional<loc::ConcreteInt> rInt = rhs.
getAs<loc::ConcreteInt>()) {
854 if (std::optional<APSIntPtr> ResultInt =
855 BasicVals.evalAPSInt(op, L.getValue(), rInt->getValue()))
856 return evalCast(nonloc::ConcreteInt(*ResultInt), resultTy, QualType{});
872 return makeTruthVal(
false, resultTy);
876 return makeTruthVal(
true, resultTy);
884 case loc::MemRegionValKind: {
885 if (std::optional<loc::ConcreteInt> rInt = rhs.
getAs<loc::ConcreteInt>()) {
890 return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
897 if (rInt->isZeroConstant()) {
899 return evalCast(lhs, resultTy, QualType{});
902 QualType boolType = getContext().BoolTy;
903 NonLoc l = evalCast(lhs, boolType, QualType{}).castAs<NonLoc>();
904 NonLoc r = makeTruthVal(
false, boolType).castAs<NonLoc>();
905 return evalBinOpNN(state, op, l, r, resultTy);
915 assert(LeftMR &&
"MemRegionValKind SVal doesn't have a region!");
928 const MemSpaceRegion *UnknownMS = MemMgr.getUnknownRegion();
931 if (LeftMS != RightMS && LeftMS != UnknownMS && RightMS != UnknownMS) {
936 return makeTruthVal(
false, resultTy);
938 return makeTruthVal(
true, resultTy);
952 if (LeftBase != RightBase &&
959 return makeTruthVal(
false, resultTy);
961 return makeTruthVal(
true, resultTy);
966 const ElementRegion *RightER = dyn_cast<ElementRegion>(RightMR);
967 const ElementRegion *LeftER = dyn_cast<ElementRegion>(LeftMR);
968 if (RightER && LeftER) {
977 SVal LeftIndexVal = LeftER->
getIndex();
978 std::optional<NonLoc> LeftIndex = LeftIndexVal.
getAs<NonLoc>();
981 LeftIndexVal = evalCast(*LeftIndex, ArrayIndexTy, QualType{});
982 LeftIndex = LeftIndexVal.
getAs<NonLoc>();
987 SVal RightIndexVal = RightER->
getIndex();
988 std::optional<NonLoc> RightIndex = RightIndexVal.
getAs<NonLoc>();
991 RightIndexVal = evalCast(*RightIndex, ArrayIndexTy, QualType{});
992 RightIndex = RightIndexVal.
getAs<NonLoc>();
998 return evalBinOpNN(state, op, *LeftIndex, *RightIndex, resultTy);
1003 const FieldRegion *RightFR = dyn_cast<FieldRegion>(RightMR);
1004 const FieldRegion *LeftFR = dyn_cast<FieldRegion>(LeftMR);
1005 if (RightFR && LeftFR) {
1014 RegionOffset RightOffset = RightMR->
getAsOffset();
1016 if (LeftOffset.
getRegion() !=
nullptr &&
1024 return UnknownVal();
1026 return makeTruthVal(left < right, resultTy);
1028 return makeTruthVal(left > right, resultTy);
1030 return makeTruthVal(left <= right, resultTy);
1032 return makeTruthVal(left >= right, resultTy);
1034 return makeTruthVal(left == right, resultTy);
1036 return makeTruthVal(left != right, resultTy);
1044 if (LHSSym && RHSSym)
1045 return makeNonLoc(LHSSym, op, RHSSym, resultTy);
1048 return UnknownVal();
1055 NonLoc rhs, QualType resultTy) {
1056 if (op >= BO_PtrMemD && op <= BO_PtrMemI) {
1057 if (
auto PTMSV = rhs.
getAs<nonloc::PointerToMember>()) {
1058 if (PTMSV->isNullMemberPointer())
1059 return UndefinedVal();
1061 auto getFieldLValue = [&](
const auto *FD) -> SVal {
1064 for (
const auto &I : *PTMSV)
1065 Result = StateMgr.getStoreManager().evalDerivedToBase(
1066 Result, I->getType(), I->isVirtual());
1068 return state->getLValue(FD,
Result);
1071 if (
const auto *FD = PTMSV->getDeclAs<FieldDecl>()) {
1072 return getFieldLValue(FD);
1074 if (
const auto *FD = PTMSV->getDeclAs<IndirectFieldDecl>()) {
1075 return getFieldLValue(FD);
1083 "arguments to comparison ops must be of the same type");
1085 SVal simplifiedRhs = simplifySVal(state, rhs);
1086 if (
auto simplifiedRhsAsNonLoc = simplifiedRhs.
getAs<NonLoc>())
1087 rhs = *simplifiedRhsAsNonLoc;
1100 if (std::optional<nonloc::ConcreteInt> rhsInt =
1101 rhs.
getAs<nonloc::ConcreteInt>()) {
1102 if (std::optional<loc::ConcreteInt> lhsInt =
1103 lhs.
getAs<loc::ConcreteInt>()) {
1104 const llvm::APSInt &leftI = lhsInt->getValue();
1105 assert(leftI.isUnsigned());
1106 llvm::APSInt rightI(rhsInt->getValue(),
true);
1110 rightI = rightI.extOrTrunc(leftI.getBitWidth());
1113 llvm::APSInt Multiplicand(rightI.getBitWidth(),
true);
1115 Multiplicand = getContext().getTypeSizeInChars(
pointeeType).getQuantity();
1116 rightI *= Multiplicand;
1121 rightI = leftI + rightI;
1124 rightI = leftI - rightI;
1127 llvm_unreachable(
"Invalid pointer arithmetic operation");
1129 return loc::ConcreteInt(getBasicValueFactory().getValue(rightI));
1134 if (
const MemRegion *region = lhs.
getAsRegion()) {
1135 rhs = convertToArrayIndex(rhs).
castAs<NonLoc>();
1136 SVal index = UnknownVal();
1137 const SubRegion *superR =
nullptr;
1140 QualType elementType;
1142 if (
const ElementRegion *elemReg = dyn_cast<ElementRegion>(region)) {
1143 assert(op == BO_Add || op == BO_Sub);
1144 index = evalBinOpNN(state, op, elemReg->getIndex(), rhs,
1145 getArrayIndexType());
1147 elementType = elemReg->getElementType();
1150 assert(op == BO_Add || op == BO_Sub);
1151 index = (op == BO_Add) ? rhs : evalMinus(rhs);
1165 elementType = getContext().CharTy;
1167 if (std::optional<NonLoc> indexV = index.getAs<NonLoc>()) {
1168 return loc::MemRegionVal(MemMgr.getElementRegion(elementType, *indexV,
1169 superR, getContext()));
1172 return UnknownVal();
1175const llvm::APSInt *SimpleSValBuilder::getConstValue(
ProgramStateRef state,
1181 return state->getConstraintManager().getSymVal(state, Sym);
1186const llvm::APSInt *SimpleSValBuilder::getConcreteValue(SVal
V) {
1187 if (std::optional<loc::ConcreteInt>
X =
V.getAs<loc::ConcreteInt>())
1188 return X->getValue().get();
1190 if (std::optional<nonloc::ConcreteInt>
X =
V.getAs<nonloc::ConcreteInt>())
1191 return X->getValue().get();
1196const llvm::APSInt *SimpleSValBuilder::getKnownValue(
ProgramStateRef state,
1198 return getConstValue(state, simplifySVal(state,
V));
1201const llvm::APSInt *SimpleSValBuilder::getMinValue(
ProgramStateRef state,
1203 V = simplifySVal(state,
V);
1209 return state->getConstraintManager().getSymMinVal(state, Sym);
1214const llvm::APSInt *SimpleSValBuilder::getMaxValue(
ProgramStateRef state,
1216 V = simplifySVal(state,
V);
1222 return state->getConstraintManager().getSymMaxVal(state, Sym);
1227SVal SimpleSValBuilder::simplifyUntilFixpoint(
ProgramStateRef State, SVal Val) {
1228 SVal SimplifiedVal = simplifySValOnce(State, Val);
1229 while (SimplifiedVal != Val) {
1230 Val = SimplifiedVal;
1231 SimplifiedVal = simplifySValOnce(State, Val);
1233 return SimplifiedVal;
1237 return simplifyUntilFixpoint(State,
V);
1245 class Simplifier :
public FullSValVisitor<Simplifier, SVal> {
1253 llvm::DenseMap<SymbolRef, SVal> Cached;
1255 static bool isUnchanged(
SymbolRef Sym, SVal Val) {
1271 const llvm::APSInt *
Const =
1272 State->getConstraintManager().getSymVal(State, Sym);
1276 return UndefinedVal();
1288 : State(State), SVB(State->getStateManager().getSValBuilder()) {}
1290 SVal VisitSymbolData(
const SymbolData *S) {
1292 if (
const llvm::APSInt *I =
1293 State->getConstraintManager().getSymVal(State, S))
1300 auto I = Cached.find(S);
1301 if (I != Cached.end())
1304 SVal LHS = getConstOrVisit(S->
getLHS());
1305 if (isUnchanged(S->
getLHS(), LHS))
1332 auto I = Cached.find(S);
1333 if (I != Cached.end())
1336 SVal RHS = getConstOrVisit(S->
getRHS());
1337 if (isUnchanged(S->
getRHS(), RHS))
1346 auto I = Cached.find(S);
1347 if (I != Cached.end())
1358 SVal LHS = getConstOrVisit(S->
getLHS());
1359 SVal RHS = getConstOrVisit(S->
getRHS());
1361 if (isUnchanged(S->
getLHS(), LHS) && isUnchanged(S->
getRHS(), RHS))
1368 SVal VisitSymbolCast(
const SymbolCast *S) {
1369 auto I = Cached.find(S);
1370 if (I != Cached.end())
1373 SVal OpVal = getConstOrVisit(OpSym);
1374 if (isUnchanged(OpSym, OpVal))
1380 SVal VisitUnarySymExpr(
const UnarySymExpr *S) {
1381 auto I = Cached.find(S);
1382 if (I != Cached.end())
1392 SVal VisitSymExpr(
SymbolRef S) {
return nonloc::SymbolVal(S); }
1394 SVal VisitMemRegion(
const MemRegion *R) {
return loc::MemRegionVal(R); }
1396 SVal VisitSymbolVal(nonloc::SymbolVal
V) {
1399 return Visit(
V.getSymbol());
1402 SVal VisitSVal(SVal
V) {
return V; }
1405 SVal SimplifiedV = Simplifier(State).Visit(
V);
static std::optional< int64_t > getConcreteValue(NonLoc SV)
Result
Implement __builtin_bit_cast and related operations.
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 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 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 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()
SVal makeSymExprValNN(BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy)
Constructs a symbolic expression for two non-location values.
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)
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
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.
PRESERVE_NONE bool Ret(InterpState &S)
bool Const(InterpState &S, const T &Arg)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
QualType pointeeType(QualType T)
const FunctionProtoType * T
U cast(CodeGen::Address addr)
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t