20 using namespace clang;
24 class SimpleSValBuilder :
public SValBuilder {
26 SVal dispatchCast(SVal val,
QualType castTy)
override;
27 SVal evalCastFromNonLoc(NonLoc val,
QualType castTy)
override;
28 SVal evalCastFromLoc(Loc val,
QualType castTy)
override;
31 SimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
ASTContext &context,
32 ProgramStateManager &stateMgr)
33 : SValBuilder(alloc, context, stateMgr) {}
34 ~SimpleSValBuilder()
override {}
36 SVal evalMinus(NonLoc val)
override;
37 SVal evalComplement(NonLoc val)
override;
39 NonLoc lhs, NonLoc rhs,
QualType resultTy)
override;
41 Loc lhs, Loc rhs,
QualType resultTy)
override;
43 Loc lhs, NonLoc rhs,
QualType resultTy)
override;
61 return new SimpleSValBuilder(alloc, context, stateMgr);
84 if (castSize == LI->getNumBits())
86 return makeLocAsInteger(LI->getLoc(), castSize);
98 if (haveSameType(T, castTy))
102 return makeNonLoc(se, T, castTy);
113 return makeTruthVal(b, castTy);
122 BasicVals.getAPSIntType(castTy).apply(i);
125 return makeIntLocVal(i);
127 return makeIntVal(i);
150 case loc::MemRegionValKind: {
153 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FTR->getDecl()))
161 return makeNonLoc(SymR->getSymbol(), BO_NE,
162 BasicVals.getZeroWithPtrWidth(), castTy);
168 case loc::GotoLabelKind:
170 return makeTruthVal(
true, castTy);
178 return makeLocAsInteger(val, BitWidth);
181 BasicVals.getAPSIntType(castTy).apply(i);
182 return makeIntVal(i);
195 SVal SimpleSValBuilder::evalMinus(
NonLoc val) {
197 case nonloc::ConcreteIntKind:
206 case nonloc::ConcreteIntKind:
217 SVal SimpleSValBuilder::MakeSymIntVal(
const SymExpr *LHS,
221 bool isIdempotent =
false;
231 return makeIntVal(0, resultTy);
249 return makeIntVal(0, resultTy);
263 return makeIntVal(0, resultTy);
264 else if (RHS.isAllOnesValue())
271 else if (RHS.isAllOnesValue()) {
272 const llvm::APSInt &Result = BasicVals.Convert(resultTy, RHS);
293 uint64_t ValWidth = RHS.getBitWidth();
296 if (ValWidth < TypeWidth) {
298 ConvertedRHS = &BasicVals.Convert(SymbolType, RHS);
299 }
else if (ValWidth == TypeWidth) {
304 ConvertedRHS = &BasicVals.Convert(SymbolType, RHS);
307 ConvertedRHS = &BasicVals.Convert(resultTy, RHS);
309 return makeNonLoc(LHS, op, *ConvertedRHS, resultTy);
315 SValBuilder &SVB = State->getStateManager().getSValBuilder();
317 SVB.evalBinOpNN(State, Rel, nonloc::SymbolVal(Sym),
318 nonloc::ConcreteInt(Bound), SVB.getConditionType());
319 if (
auto DV = Result.getAs<DefinedSVal>()) {
320 return !State->assume(*DV,
false);
332 SValBuilder &SVB = State->getStateManager().getSValBuilder();
333 BasicValueFactory &BV = SVB.getBasicValueFactory();
337 "This only works with signed integers!");
338 APSIntType AT = BV.getAPSIntType(T);
340 llvm::APSInt Max = AT.getMaxValue() / AT.getValue(4), Min = -Max;
348 assert(!AT.isUnsigned() &&
349 "This only works with signed integers!");
351 llvm::APSInt Max = AT.getMaxValue() / AT.getValue(4), Min = -Max;
352 return (I <= Max) && (I >= -Max);
355 static std::pair<SymbolRef, llvm::APSInt>
357 if (
const auto *SymInt = dyn_cast<SymIntExpr>(Sym))
359 return std::make_pair(SymInt->getLHS(),
360 (SymInt->getOpcode() == BO_Add) ?
362 (-SymInt->getRHS()));
365 return std::make_pair(Sym, BV.getValue(0, Sym->getType()));
375 SValBuilder &SVB = State->getStateManager().getSValBuilder();
376 BasicValueFactory &BV = SVB.getBasicValueFactory();
377 SymbolManager &SymMgr = SVB.getSymbolManager();
380 assert(SymTy == RSym->getType() &&
381 "Symbols are not of the same type!");
382 assert(APSIntType(LInt) == BV.getAPSIntType(SymTy) &&
383 "Integers are not of the same type as symbols!");
384 assert(APSIntType(RInt) == BV.getAPSIntType(SymTy) &&
385 "Integers are not of the same type as symbols!");
389 ResultTy = SVB.getConditionType();
393 llvm_unreachable(
"Operation not suitable for unchecked rearrangement!");
397 return SVB.evalBinOpNN(State, Op, nonloc::ConcreteInt(LInt),
398 nonloc::ConcreteInt(RInt), ResultTy)
409 ResultSym = SymMgr.getSymSymExpr(RSym, BO_Sub, LSym, SymTy);
411 ResultInt = LInt - RInt;
413 ResultSym = SymMgr.getSymSymExpr(LSym, BO_Sub, RSym, SymTy);
415 ResultInt = RInt - LInt;
418 ResultSym = SymMgr.getSymSymExpr(LSym, Op, RSym, SymTy);
419 ResultInt = (Op == BO_Add) ? (LInt + RInt) : (LInt - RInt);
423 ResultInt = -ResultInt;
425 }
else if (ResultInt == 0) {
427 return nonloc::SymbolVal(ResultSym);
430 const llvm::APSInt &PersistentResultInt = BV.getValue(ResultInt);
431 return nonloc::SymbolVal(
432 SymMgr.getSymIntExpr(ResultSym, ResultOp, PersistentResultInt, ResultTy));
440 return Sym->getType() == Ty &&
449 ProgramStateManager &StateMgr = State->getStateManager();
450 SValBuilder &SVB = StateMgr.getSValBuilder();
456 StateMgr.getOwningEngine().getAnalysisManager().getAnalyzerOptions();
461 if(!Opts.ShouldAggressivelySimplifyBinaryOperation)
469 SingleTy = LSym->getType();
470 if (ResultTy != SVB.getConditionType())
475 if (LSym->getType() != SingleTy)
482 assert(!SingleTy.
isNull() &&
"We should have figured out the type by now!");
489 if (!RSym || RSym->getType() != SingleTy)
492 BasicValueFactory &BV = State->getBasicVals();
506 NonLoc lhs, NonLoc rhs,
508 NonLoc InputLHS = lhs;
509 NonLoc InputRHS = rhs;
519 return makeTruthVal(
true, resultTy);
523 return makeTruthVal(
false, resultTy);
527 return makeIntVal(0, resultTy);
528 return evalCastFromNonLoc(makeIntVal(0,
false), resultTy);
531 return evalCastFromNonLoc(lhs, resultTy);
535 switch (lhs.getSubKind()) {
537 return makeSymExprValNN(op, lhs, rhs, resultTy);
538 case nonloc::PointerToMemberKind: {
539 assert(rhs.getSubKind() == nonloc::PointerToMemberKind &&
540 "Both SVals should have pointer-to-member-type");
543 auto LPTMD = LPTM.getPTMData(), RPTMD = RPTM.getPTMData();
546 return makeTruthVal(LPTMD == RPTMD, resultTy);
548 return makeTruthVal(LPTMD != RPTMD, resultTy);
553 case nonloc::LocAsIntegerKind: {
554 Loc lhsL = lhs.castAs<nonloc::LocAsInteger>().getLoc();
555 switch (rhs.getSubKind()) {
556 case nonloc::LocAsIntegerKind:
561 return evalBinOpLL(
state, op, lhsL,
562 rhs.castAs<nonloc::LocAsInteger>().getLoc(),
564 case nonloc::ConcreteIntKind: {
579 if (
SymbolRef lSym = lhs.getAsLocSymbol(
true))
580 BasicVals.getAPSIntType(lSym->getType()).apply(i);
582 BasicVals.getAPSIntType(Context.
VoidPtrTy).apply(i);
583 return evalBinOpLL(
state, op, lhsL, makeLoc(i), resultTy);
588 return makeTruthVal(
false, resultTy);
590 return makeTruthVal(
true, resultTy);
593 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
597 case nonloc::ConcreteIntKind: {
607 APSIntType CompareType =
std::max(APSIntType(LHSValue),
608 APSIntType(RHSValue));
609 CompareType.apply(LHSValue);
610 CompareType.apply(RHSValue);
612 APSIntType IntType = BasicVals.getAPSIntType(resultTy);
613 IntType.apply(LHSValue);
614 IntType.apply(RHSValue);
618 BasicVals.evalAPSInt(op, LHSValue, RHSValue);
620 return UndefinedVal();
622 return nonloc::ConcreteInt(*Result);
647 if (LHSValue.isAllOnesValue() && LHSValue.isSigned())
648 return evalCastFromNonLoc(lhs, resultTy);
653 return evalCastFromNonLoc(lhs, resultTy);
654 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
656 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
659 case nonloc::SymbolValKind: {
661 SymbolRef Sym = lhs.castAs<nonloc::SymbolVal>().getSymbol();
664 if (
const SymIntExpr *symIntExpr = dyn_cast<SymIntExpr>(Sym)) {
667 if (op == BO_EQ && rhs.isZeroConstant()) {
678 llvm_unreachable(
"Logical operators handled by branching logic.");
691 llvm_unreachable(
"'=' and ',' operators handled by ExprEngine.");
694 llvm_unreachable(
"Pointer arithmetic not handled here.");
702 resultTy == getConditionType());
703 assert(symIntExpr->getType()->isBooleanType() ||
704 getContext().hasSameUnqualifiedType(symIntExpr->getType(),
705 getConditionType()));
708 return makeNonLoc(symIntExpr->getLHS(), opc,
709 symIntExpr->getRHS(), resultTy);
727 APSIntType IntType = BasicVals.getAPSIntType(resultTy);
728 const llvm::APSInt &first = IntType.convert(symIntExpr->getRHS());
729 const llvm::APSInt &second = IntType.convert(*RHSValue);
733 newRHS = BasicVals.evalAPSInt(BO_Add, first, second);
735 newRHS = BasicVals.evalAPSInt(BO_Sub, first, second);
737 assert(newRHS &&
"Invalid operation despite common type!");
738 rhs = nonloc::ConcreteInt(*newRHS);
739 lhs = nonloc::SymbolVal(symIntExpr->getLHS());
746 return MakeSymIntVal(symIntExpr, op, *RHSValue, resultTy);
753 SVal simplifiedLhs = simplifySVal(
state, lhs);
754 if (simplifiedLhs != lhs)
755 if (
auto simplifiedLhsAsNonLoc = simplifiedLhs.getAs<NonLoc>()) {
756 lhs = *simplifiedLhsAsNonLoc;
762 return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
768 return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
775 const FieldRegion *RightFR,
778 SimpleSValBuilder &SVB) {
786 if (LeftFR->getSuperRegion() != RightFR->getSuperRegion())
789 const FieldDecl *LeftFD = LeftFR->getDecl();
790 const FieldDecl *RightFD = RightFR->getDecl();
801 return SVB.makeTruthVal(
false, resultTy);
803 return SVB.makeTruthVal(
true, resultTy);
809 bool leftFirst = (op == BO_LT || op == BO_LE);
810 for (
const auto *I : RD->
fields()) {
812 return SVB.makeTruthVal(leftFirst, resultTy);
814 return SVB.makeTruthVal(!leftFirst, resultTy);
817 llvm_unreachable(
"Fields not found in parent record's definition");
838 llvm_unreachable(
"Unimplemented operation for two identical values");
840 return makeZeroVal(resultTy);
844 return makeTruthVal(
true, resultTy);
848 return makeTruthVal(
false, resultTy);
852 switch (lhs.getSubKind()) {
854 llvm_unreachable(
"Ordering not implemented for this Loc.");
856 case loc::GotoLabelKind:
858 if (rhs.isZeroConstant()) {
863 return evalCastFromLoc(lhs, resultTy);
867 return makeTruthVal(
false, resultTy);
871 return makeTruthVal(
true, resultTy);
881 case loc::ConcreteIntKind: {
884 if (
SymbolRef rSym = rhs.getAsLocSymbol()) {
892 return makeNonLoc(rSym, op, lVal, resultTy);
898 lhs.castAs<loc::ConcreteInt>().evalBinOp(BasicVals, op, *rInt);
900 return evalCastFromNonLoc(*Result, resultTy);
902 assert(!ResultVal.getAs<Loc>() &&
"Loc-Loc ops should not produce Locs");
910 assert(rhs.getAs<loc::MemRegionVal>() || rhs.getAs<loc::GotoLabel>());
911 if (lhs.isZeroConstant()) {
918 return makeTruthVal(
false, resultTy);
922 return makeTruthVal(
true, resultTy);
930 case loc::MemRegionValKind: {
934 if (
SymbolRef lSym = lhs.getAsLocSymbol(
true)) {
936 return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
943 if (rInt->isZeroConstant()) {
945 return evalCastFromLoc(lhs, resultTy);
948 QualType boolType = getContext().BoolTy;
949 NonLoc l = evalCastFromLoc(lhs, boolType).castAs<NonLoc>();
950 NonLoc r = makeTruthVal(
false, boolType).castAs<NonLoc>();
951 return evalBinOpNN(
state, op, l, r, resultTy);
960 const MemRegion *LeftMR = lhs.getAsRegion();
961 assert(LeftMR &&
"MemRegionValKind SVal doesn't have a region!");
963 const MemRegion *RightMR = rhs.getAsRegion();
970 const MemRegion *LeftBase = LeftMR->getBaseRegion();
971 const MemRegion *RightBase = RightMR->getBaseRegion();
972 const MemSpaceRegion *LeftMS = LeftBase->getMemorySpace();
973 const MemSpaceRegion *RightMS = RightBase->getMemorySpace();
974 const MemSpaceRegion *UnknownMS = MemMgr.getUnknownRegion();
979 if (LeftMS != RightMS &&
980 ((LeftMS != UnknownMS && RightMS != UnknownMS) ||
981 (isa<StackSpaceRegion>(LeftMS) || isa<StackSpaceRegion>(RightMS)))) {
986 return makeTruthVal(
false, resultTy);
988 return makeTruthVal(
true, resultTy);
1002 if (LeftBase != RightBase &&
1003 ((!isa<SymbolicRegion>(LeftBase) && !isa<SymbolicRegion>(RightBase)) ||
1004 (isa<HeapSpaceRegion>(LeftMS) || isa<HeapSpaceRegion>(RightMS))) ){
1007 return UnknownVal();
1009 return makeTruthVal(
false, resultTy);
1011 return makeTruthVal(
true, resultTy);
1016 const ElementRegion *RightER = dyn_cast<ElementRegion>(RightMR);
1017 const ElementRegion *LeftER = dyn_cast<ElementRegion>(LeftMR);
1018 if (RightER && LeftER) {
1023 if (LeftER->getSuperRegion() == RightER->getSuperRegion() &&
1024 LeftER->getElementType() == RightER->getElementType()) {
1027 SVal LeftIndexVal = LeftER->getIndex();
1030 return UnknownVal();
1031 LeftIndexVal = evalCastFromNonLoc(*LeftIndex, ArrayIndexTy);
1032 LeftIndex = LeftIndexVal.getAs<NonLoc>();
1034 return UnknownVal();
1037 SVal RightIndexVal = RightER->getIndex();
1040 return UnknownVal();
1041 RightIndexVal = evalCastFromNonLoc(*RightIndex, ArrayIndexTy);
1042 RightIndex = RightIndexVal.getAs<NonLoc>();
1044 return UnknownVal();
1048 return evalBinOpNN(
state, op, *LeftIndex, *RightIndex, resultTy);
1053 const FieldRegion *RightFR = dyn_cast<FieldRegion>(RightMR);
1054 const FieldRegion *LeftFR = dyn_cast<FieldRegion>(LeftMR);
1055 if (RightFR && LeftFR) {
1063 RegionOffset LeftOffset = LeftMR->getAsOffset();
1064 RegionOffset RightOffset = RightMR->getAsOffset();
1066 if (LeftOffset.getRegion() !=
nullptr &&
1067 LeftOffset.getRegion() == RightOffset.getRegion() &&
1068 !LeftOffset.hasSymbolicOffset() && !RightOffset.hasSymbolicOffset()) {
1069 int64_t left = LeftOffset.getOffset();
1070 int64_t right = RightOffset.getOffset();
1074 return UnknownVal();
1076 return makeTruthVal(left < right, resultTy);
1078 return makeTruthVal(left > right, resultTy);
1080 return makeTruthVal(left <= right, resultTy);
1082 return makeTruthVal(left >= right, resultTy);
1084 return makeTruthVal(left == right, resultTy);
1086 return makeTruthVal(left != right, resultTy);
1092 SymbolRef LHSSym = lhs.getAsLocSymbol();
1093 SymbolRef RHSSym = rhs.getAsLocSymbol();
1094 if (LHSSym && RHSSym)
1095 return makeNonLoc(LHSSym, op, RHSSym, resultTy);
1098 return UnknownVal();
1105 Loc lhs, NonLoc rhs,
QualType resultTy) {
1106 if (op >= BO_PtrMemD && op <= BO_PtrMemI) {
1108 if (PTMSV->isNullMemberPointer())
1109 return UndefinedVal();
1113 for (
const auto &I : *PTMSV)
1114 Result = StateMgr.getStoreManager().evalDerivedToBase(
1115 Result, I->getType(),I->isVirtual());
1116 return state->getLValue(FD, Result);
1124 "arguments to comparison ops must be of the same type");
1127 if (rhs.isZeroConstant())
1131 if (lhs.isZeroConstant())
1140 assert(leftI.isUnsigned());
1145 rightI = rightI.extOrTrunc(leftI.getBitWidth());
1150 Multiplicand = getContext().getTypeSizeInChars(pointeeType).getQuantity();
1151 rightI *= Multiplicand;
1156 rightI = leftI + rightI;
1159 rightI = leftI - rightI;
1162 llvm_unreachable(
"Invalid pointer arithmetic operation");
1164 return loc::ConcreteInt(getBasicValueFactory().
getValue(rightI));
1169 if (
const MemRegion *region = lhs.getAsRegion()) {
1170 rhs = convertToArrayIndex(rhs).castAs<NonLoc>();
1171 SVal index = UnknownVal();
1172 const SubRegion *superR =
nullptr;
1177 if (
const ElementRegion *elemReg = dyn_cast<ElementRegion>(region)) {
1178 assert(op == BO_Add || op == BO_Sub);
1179 index = evalBinOpNN(
state, op, elemReg->getIndex(), rhs,
1180 getArrayIndexType());
1181 superR = cast<SubRegion>(elemReg->getSuperRegion());
1182 elementType = elemReg->getElementType();
1184 else if (isa<SubRegion>(region)) {
1185 assert(op == BO_Add || op == BO_Sub);
1186 index = (op == BO_Add) ? rhs : evalMinus(rhs);
1187 superR = cast<SubRegion>(region);
1200 elementType = getContext().CharTy;
1203 return loc::MemRegionVal(MemMgr.getElementRegion(elementType, *indexV,
1204 superR, getContext()));
1207 return UnknownVal();
1212 V = simplifySVal(
state, V);
1213 if (V.isUnknownOrUndef())
1217 return &X->getValue();
1220 return &X->getValue();
1223 return state->getConstraintManager().getSymVal(
state, Sym);
1234 class Simplifier :
public FullSValVisitor<Simplifier, SVal> {
1242 llvm::DenseMap<SymbolRef, SVal> Cached;
1244 static bool isUnchanged(
SymbolRef Sym, SVal Val) {
1245 return Sym == Val.getAsSymbol();
1254 return cache(Sym, SVB.makeSymbolVal(Sym));
1259 :
State(State), SVB(State->getStateManager().getSValBuilder()) {}
1261 SVal VisitSymbolData(
const SymbolData *S) {
1264 SVB.getKnownValue(State, SVB.makeSymbolVal(S)))
1265 return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I)
1266 : (SVal)SVB.makeIntVal(*I);
1267 return SVB.makeSymbolVal(S);
1273 SVal VisitSymIntExpr(
const SymIntExpr *S) {
1274 auto I = Cached.find(S);
1275 if (I != Cached.end())
1278 SVal LHS = Visit(S->getLHS());
1279 if (isUnchanged(S->getLHS(), LHS))
1292 if (
SymbolRef Sym = LHS.getAsSymbol()) {
1294 LHS = SVB.makeLoc(Sym);
1296 RHS = SVB.makeIntLocVal(S->getRHS());
1298 RHS = SVB.makeIntVal(S->getRHS());
1302 S, SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->
getType()));
1305 SVal VisitSymSymExpr(
const SymSymExpr *S) {
1306 auto I = Cached.find(S);
1307 if (I != Cached.end())
1318 SVal LHS = Visit(S->getLHS());
1319 SVal RHS = Visit(S->getRHS());
1320 if (isUnchanged(S->getLHS(), LHS) && isUnchanged(S->getRHS(), RHS))
1324 S, SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType()));
1327 SVal VisitSymExpr(
SymbolRef S) {
return nonloc::SymbolVal(S); }
1329 SVal VisitMemRegion(
const MemRegion *R) {
return loc::MemRegionVal(R); }
1331 SVal VisitNonLocSymbolVal(nonloc::SymbolVal V) {
1334 return Visit(V.getSymbol());
1337 SVal VisitSVal(SVal V) {
return V; }
1341 static bool isReentering =
false;
1345 isReentering =
true;
1346 SVal SimplifiedV = Simplifier(
State).Visit(V);
1347 isReentering =
false;
Represents a function declaration or definition.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
SValBuilder * createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
static bool isWithinConstantOverflowBounds(SymbolRef Sym, ProgramStateRef State)
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined...
Value representing integer constant.
bool isAdditiveOp() const
Represents a struct/union/class.
const SymbolicRegion * getSymbolicBase() const
If this is a symbolic region, returns the region.
static NonLoc doRearrangeUnchecked(ProgramStateRef State, BinaryOperator::Opcode Op, SymbolRef LSym, llvm::APSInt LInt, SymbolRef RSym, llvm::APSInt RInt)
const SymExpr * SymbolRef
static Opcode reverseComparisonOp(Opcode Opc)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static bool isInRelation(BinaryOperator::Opcode Rel, SymbolRef Sym, llvm::APSInt Bound, ProgramStateRef State)
Value representing pointer-to-member.
field_range fields() const
Represents a member of a struct/union/class.
bool isReferenceType() const
__DEVICE__ int max(int __a, int __b)
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
const SymExpr * getAsSymbolicExpression() const
getAsSymbolicExpression - If this Sval wraps a symbolic expression then return that expression...
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
static bool isLocType(QualType T)
static bool shouldRearrange(ProgramStateRef State, BinaryOperator::Opcode Op, SymbolRef Sym, llvm::APSInt Int, QualType Ty)
virtual QualType getType() const =0
static std::pair< SymbolRef, llvm::APSInt > decomposeSymbol(SymbolRef Sym, BasicValueFactory &BV)
static Opcode negateComparisonOp(Opcode Opc)
unsigned getSubKind() const
SymbolicRegion - A special, "non-concrete" region.
static SVal getValue(SVal val, SValBuilder &svalBuilder)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
bool isComparisonOp() const
FunctionCodeRegion - A region that represents code texts of function.
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...
bool isAnyPointerType() const
Dataflow Directional Tag Classes.
bool isBooleanType() const
Represents symbolic expression that isn't a location.
unsigned getIntWidth(QualType T) const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
static 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)