21 using namespace clang;
32 SimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
ASTContext &context,
35 ~SimpleSValBuilder()
override {}
55 const llvm::APSInt &RHS,
QualType resultTy);
62 return new SimpleSValBuilder(alloc, context, stateMgr);
85 if (castSize == LI->getNumBits())
87 return makeLocAsInteger(LI->getLoc(), castSize);
99 if (haveSameType(T, castTy))
103 return makeNonLoc(se, T, castTy);
114 return makeTruthVal(b, castTy);
123 BasicVals.getAPSIntType(castTy).apply(i);
126 return makeIntLocVal(i);
128 return makeIntVal(i);
151 case loc::MemRegionValKind: {
154 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FTR->getDecl()))
162 return makeNonLoc(SymR->getSymbol(), BO_NE,
163 BasicVals.getZeroWithPtrWidth(), castTy);
169 case loc::GotoLabelKind:
171 return makeTruthVal(
true, castTy);
179 return makeLocAsInteger(val, BitWidth);
182 BasicVals.getAPSIntType(castTy).apply(i);
183 return makeIntVal(i);
196 SVal SimpleSValBuilder::evalMinus(
NonLoc val) {
198 case nonloc::ConcreteIntKind:
207 case nonloc::ConcreteIntKind:
218 SVal SimpleSValBuilder::MakeSymIntVal(
const SymExpr *LHS,
220 const llvm::APSInt &RHS,
222 bool isIdempotent =
false;
232 return makeIntVal(0, resultTy);
250 return makeIntVal(0, resultTy);
264 return makeIntVal(0, resultTy);
265 else if (RHS.isAllOnesValue())
272 else if (RHS.isAllOnesValue()) {
273 const llvm::APSInt &Result = BasicVals.Convert(resultTy, RHS);
287 const llvm::APSInt *ConvertedRHS = &RHS;
294 uint64_t ValWidth = RHS.getBitWidth();
297 if (ValWidth < TypeWidth) {
299 ConvertedRHS = &BasicVals.Convert(SymbolType, RHS);
300 }
else if (ValWidth == TypeWidth) {
305 ConvertedRHS = &BasicVals.Convert(SymbolType, RHS);
308 ConvertedRHS = &BasicVals.Convert(resultTy, RHS);
310 return makeNonLoc(LHS, op, *ConvertedRHS, resultTy);
316 SValBuilder &SVB = State->getStateManager().getSValBuilder();
321 return !State->assume(*DV,
false);
333 SValBuilder &SVB = State->getStateManager().getSValBuilder();
338 "This only works with signed integers!");
341 llvm::APSInt Max = AT.
getMaxValue() / AT.getValue(4), Min = -Max;
350 "This only works with signed integers!");
353 return (I <= Max) && (I >= -Max);
356 static std::pair<SymbolRef, llvm::APSInt>
358 if (
const auto *SymInt = dyn_cast<SymIntExpr>(Sym))
360 return std::make_pair(SymInt->getLHS(),
361 (SymInt->getOpcode() == BO_Add) ?
363 (-SymInt->getRHS()));
366 return std::make_pair(Sym, BV.getValue(0, Sym->
getType()));
376 SValBuilder &SVB = State->getStateManager().getSValBuilder();
381 assert(SymTy == RSym->
getType() &&
382 "Symbols are not of the same type!");
384 "Integers are not of the same type as symbols!");
386 "Integers are not of the same type as symbols!");
394 llvm_unreachable(
"Operation not suitable for unchecked rearrangement!");
404 llvm::APSInt ResultInt;
412 ResultInt = LInt - RInt;
416 ResultInt = RInt - LInt;
420 ResultInt = (Op == BO_Add) ? (LInt + RInt) : (LInt - RInt);
424 ResultInt = -ResultInt;
426 }
else if (ResultInt == 0) {
431 const llvm::APSInt &PersistentResultInt = BV.getValue(ResultInt);
433 SymMgr.
getSymIntExpr(ResultSym, ResultOp, PersistentResultInt, ResultTy));
462 if(!Opts.shouldAggressivelySimplifyBinaryOperation())
476 if (LSym->
getType() != SingleTy)
486 assert(!SingleTy.
isNull() &&
"We should have figured out the type by now!");
489 if (!RSym || RSym->getType() != SingleTy)
493 llvm::APSInt LInt, RInt;
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);
537 return makeSymExprValNN(state, 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: {
556 case nonloc::LocAsIntegerKind:
561 return evalBinOpLL(state, op, lhsL,
564 case nonloc::ConcreteIntKind: {
574 BasicVals.getAPSIntType(Context.
VoidPtrTy).apply(i);
575 return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy);
580 return makeTruthVal(
false, resultTy);
582 return makeTruthVal(
true, resultTy);
585 return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
589 case nonloc::ConcreteIntKind: {
593 if (
const llvm::APSInt *KnownRHSValue = getKnownValue(state, rhs)) {
594 llvm::APSInt RHSValue = *KnownRHSValue;
601 CompareType.
apply(LHSValue);
602 CompareType.
apply(RHSValue);
604 APSIntType IntType = BasicVals.getAPSIntType(resultTy);
605 IntType.
apply(LHSValue);
606 IntType.
apply(RHSValue);
609 const llvm::APSInt *Result =
610 BasicVals.evalAPSInt(op, LHSValue, RHSValue);
639 if (LHSValue.isAllOnesValue() && LHSValue.isSigned())
640 return evalCastFromNonLoc(lhs, resultTy);
645 return evalCastFromNonLoc(lhs, resultTy);
646 return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
648 return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
651 case nonloc::SymbolValKind: {
656 if (
const SymIntExpr *symIntExpr = dyn_cast<SymIntExpr>(Sym)) {
670 llvm_unreachable(
"Logical operators handled by branching logic.");
683 llvm_unreachable(
"'=' and ',' operators handled by ExprEngine.");
686 llvm_unreachable(
"Pointer arithmetic not handled here.");
694 resultTy == getConditionType());
695 assert(symIntExpr->getType()->isBooleanType() ||
696 getContext().hasSameUnqualifiedType(symIntExpr->getType(),
697 getConditionType()));
700 return makeNonLoc(symIntExpr->getLHS(), opc,
701 symIntExpr->getRHS(), resultTy);
706 if (
const llvm::APSInt *RHSValue = getKnownValue(state, rhs)) {
719 APSIntType IntType = BasicVals.getAPSIntType(resultTy);
720 const llvm::APSInt &first = IntType.
convert(symIntExpr->getRHS());
721 const llvm::APSInt &second = IntType.
convert(*RHSValue);
723 const llvm::APSInt *newRHS;
725 newRHS = BasicVals.evalAPSInt(BO_Add, first, second);
727 newRHS = BasicVals.evalAPSInt(BO_Sub, first, second);
729 assert(newRHS &&
"Invalid operation despite common type!");
738 return MakeSymIntVal(symIntExpr, op, *RHSValue, resultTy);
745 SVal simplifiedLhs = simplifySVal(state, lhs);
746 if (simplifiedLhs != lhs)
747 if (
auto simplifiedLhsAsNonLoc = simplifiedLhs.
getAs<
NonLoc>()) {
748 lhs = *simplifiedLhsAsNonLoc;
753 if (
const llvm::APSInt *RHSValue = getKnownValue(state, rhs))
754 return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
760 return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
770 SimpleSValBuilder &SVB) {
793 return SVB.makeTruthVal(
false, resultTy);
795 return SVB.makeTruthVal(
true, resultTy);
801 bool leftFirst = (op == BO_LT || op == BO_LE);
802 for (
const auto *I : RD->
fields()) {
804 return SVB.makeTruthVal(leftFirst, resultTy);
806 return SVB.makeTruthVal(!leftFirst, resultTy);
809 llvm_unreachable(
"Fields not found in parent record's definition");
830 llvm_unreachable(
"Unimplemented operation for two identical values");
832 return makeZeroVal(resultTy);
836 return makeTruthVal(
true, resultTy);
840 return makeTruthVal(
false, resultTy);
846 llvm_unreachable(
"Ordering not implemented for this Loc.");
848 case loc::GotoLabelKind:
855 return evalCastFromLoc(lhs, resultTy);
859 return makeTruthVal(
false, resultTy);
863 return makeTruthVal(
true, resultTy);
873 case loc::ConcreteIntKind: {
884 return makeNonLoc(rSym, op, lVal, resultTy);
892 return evalCastFromNonLoc(*Result, resultTy);
894 assert(!ResultVal.
getAs<
Loc>() &&
"Loc-Loc ops should not produce Locs");
910 return makeTruthVal(
false, resultTy);
914 return makeTruthVal(
true, resultTy);
922 case loc::MemRegionValKind: {
928 return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
935 if (rInt->isZeroConstant()) {
937 return evalCastFromLoc(lhs, resultTy);
940 QualType boolType = getContext().BoolTy;
943 return evalBinOpNN(state, op, l, r, resultTy);
953 assert(LeftMR &&
"MemRegionValKind SVal doesn't have a region!");
971 if (LeftMS != RightMS &&
972 ((LeftMS != UnknownMS && RightMS != UnknownMS) ||
973 (isa<StackSpaceRegion>(LeftMS) || isa<StackSpaceRegion>(RightMS)))) {
978 return makeTruthVal(
false, resultTy);
980 return makeTruthVal(
true, resultTy);
994 if (LeftBase != RightBase &&
995 ((!isa<SymbolicRegion>(LeftBase) && !isa<SymbolicRegion>(RightBase)) ||
996 (isa<HeapSpaceRegion>(LeftMS) || isa<HeapSpaceRegion>(RightMS))) ){
1001 return makeTruthVal(
false, resultTy);
1003 return makeTruthVal(
true, resultTy);
1010 if (RightER && LeftER) {
1019 SVal LeftIndexVal = LeftER->getIndex();
1023 LeftIndexVal = evalCastFromNonLoc(*LeftIndex, ArrayIndexTy);
1033 RightIndexVal = evalCastFromNonLoc(*RightIndex, ArrayIndexTy);
1040 return evalBinOpNN(state, op, *LeftIndex, *RightIndex, resultTy);
1047 if (RightFR && LeftFR) {
1058 if (LeftOffset.
getRegion() !=
nullptr &&
1062 int64_t right = RightOffset.
getOffset();
1068 return makeTruthVal(left < right, resultTy);
1070 return makeTruthVal(left > right, resultTy);
1072 return makeTruthVal(left <= right, resultTy);
1074 return makeTruthVal(left >= right, resultTy);
1076 return makeTruthVal(left == right, resultTy);
1078 return makeTruthVal(left != right, resultTy);
1086 if (LHSSym && RHSSym)
1087 return makeNonLoc(LHSSym, op, RHSSym, resultTy);
1098 if (op >= BO_PtrMemD && op <= BO_PtrMemI) {
1100 if (PTMSV->isNullMemberPointer())
1105 for (
const auto &I : *PTMSV)
1106 Result = StateMgr.getStoreManager().evalDerivedToBase(
1107 Result, I->getType(),I->isVirtual());
1108 return state->getLValue(FD, Result);
1116 "arguments to comparison ops must be of the same type");
1131 const llvm::APSInt &leftI = lhsInt->getValue();
1132 assert(leftI.isUnsigned());
1133 llvm::APSInt rightI(rhsInt->getValue(),
true);
1137 rightI = rightI.extOrTrunc(leftI.getBitWidth());
1140 llvm::APSInt Multiplicand(rightI.getBitWidth(),
true);
1142 Multiplicand = getContext().getTypeSizeInChars(pointeeType).getQuantity();
1143 rightI *= Multiplicand;
1148 rightI = leftI + rightI;
1151 rightI = leftI - rightI;
1154 llvm_unreachable(
"Invalid pointer arithmetic operation");
1169 if (
const ElementRegion *elemReg = dyn_cast<ElementRegion>(region)) {
1170 assert(op == BO_Add || op == BO_Sub);
1171 index = evalBinOpNN(state, op, elemReg->getIndex(), rhs,
1172 getArrayIndexType());
1173 superR = cast<SubRegion>(elemReg->getSuperRegion());
1174 elementType = elemReg->getElementType();
1176 else if (isa<SubRegion>(region)) {
1177 assert(op == BO_Add || op == BO_Sub);
1178 index = (op == BO_Add) ? rhs : evalMinus(rhs);
1179 superR = cast<SubRegion>(region);
1192 elementType = getContext().CharTy;
1196 superR, getContext()));
1202 const llvm::APSInt *SimpleSValBuilder::getKnownValue(
ProgramStateRef state,
1208 return &X->getValue();
1211 return &X->getValue();
1214 return state->getConstraintManager().getSymVal(state, Sym);
1233 llvm::DenseMap<SymbolRef, SVal> Cached;
1250 :
State(State), SVB(State->getStateManager().getSValBuilder()) {}
1254 if (
const llvm::APSInt *I =
1265 auto I = Cached.find(S);
1266 if (I != Cached.end())
1270 if (isUnchanged(S->
getLHS(), LHS))
1283 if (
SymbolRef Sym = LHS.getAsSymbol()) {
1297 auto I = Cached.find(S);
1298 if (I != Cached.end())
1311 if (isUnchanged(S->
getLHS(), LHS) && isUnchanged(S->
getRHS(), RHS))
1328 SVal VisitSVal(
SVal V) {
return V; }
1332 static bool isReentering =
false;
1336 isReentering =
true;
1337 SVal SimplifiedV = Simplifier(State).Visit(V);
1338 isReentering =
false;
Represents a function declaration or definition.
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
SymbolManager & getSymbolManager()
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)
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined...
const MemRegion * getRegion() const
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
Value representing integer constant.
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
QualType getElementType() const
bool isAdditiveOp() const
const MemRegion * getSuperRegion() const
Represents a struct/union/class.
const PTMDataType getPTMData() const
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)
static Opcode reverseComparisonOp(Opcode Opc)
SVal makeSymbolVal(SymbolRef Sym)
Make an SVal that represents the given symbol.
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
const FieldDecl * getDecl() const
Represents a member of a struct/union/class.
bool isReferenceType() const
SubEngine * getOwningEngine()
FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses...
SValBuilder & getSValBuilder()
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)
const SymIntExpr * getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt &rhs, QualType t)
loc::ConcreteInt makeIntLocVal(const llvm::APSInt &integer)
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.
const MemSpaceRegion * getMemorySpace() const
virtual QualType getType() const =0
static std::pair< SymbolRef, llvm::APSInt > decomposeSymbol(SymbolRef Sym, BasicValueFactory &BV)
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
static Opcode negateComparisonOp(Opcode Opc)
unsigned getSubKind() const
Loc makeLoc(SymbolRef sym)
SymbolicRegion - A special, "non-concrete" region.
AnalyzerOptions & getAnalyzerOptions() override
QualType getConditionType() const
static SVal getValue(SVal val, SValBuilder &svalBuilder)
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
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
llvm::APSInt getMaxValue() const LLVM_READONLY
Returns the maximum value for this type.
const SymSymExpr * getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t)
const SymExpr * getLHS() const
FunctionCodeRegion - A region that represents code texts of function.
const MemRegion * getAsRegion() const
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
QualType getType() const override
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.
llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY
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...
Dataflow Directional Tag Classes.
bool isZeroConstant() const
const llvm::APSInt & getRHS() const
bool isBooleanType() const
Represents symbolic expression that isn't a location.
const SymExpr * getRHS() const
unsigned getIntWidth(QualType T) const
APSIntType getAPSIntType(QualType T) const
Returns the type of the APSInt used to store values of the given QualType.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
BasicValueFactory & getBasicValueFactory()
SubRegion - A region that subsets another larger region.
SymbolRef getSymbol() const
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
int64_t getOffset() const
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 ...
BinaryOperator::Opcode getOpcode() const
void apply(llvm::APSInt &Value) const
Convert a given APSInt, in place, to match this type.
static Optional< NonLoc > tryRearrange(ProgramStateRef State, BinaryOperator::Opcode Op, NonLoc Lhs, NonLoc Rhs, QualType ResultTy)
const MemRegion * getBaseRegion() const
ElementRegin is used to represent both array elements and casts.
virtual const llvm::APSInt * getKnownValue(ProgramStateRef state, SVal val)=0
Evaluates a given SVal.
__DEVICE__ int max(int __a, int __b)
Represents a symbolic expression like 'x' + 'y'.
bool hasSymbolicOffset() const
bool isUnknownOrUndef() const
A symbol representing data which can be stored in a memory location (region).
const SymExpr * getLHS() const
virtual AnalysisManager & getAnalysisManager()=0
static SVal evalBinOpFieldRegionFieldRegion(const FieldRegion *LeftFR, const FieldRegion *RightFR, BinaryOperator::Opcode op, QualType resultTy, SimpleSValBuilder &SVB)