34 using namespace SVFUtil;
58 if (intType->isSigned())
60 ub =
static_cast<s64_t>(std::numeric_limits<s32_t>::max());
61 lb =
static_cast<s64_t>(std::numeric_limits<s32_t>::min());
65 ub =
static_cast<s64_t>(std::numeric_limits<u32_t>::max());
66 lb =
static_cast<s64_t>(std::numeric_limits<u32_t>::min());
71 if (intType->isSigned())
73 ub =
static_cast<s64_t>(std::numeric_limits<s16_t>::max());
74 lb =
static_cast<s64_t>(std::numeric_limits<s16_t>::min());
78 ub =
static_cast<s64_t>(std::numeric_limits<u16_t>::max());
79 lb =
static_cast<s64_t>(std::numeric_limits<u16_t>::min());
84 if (intType->isSigned())
86 ub =
static_cast<s64_t>(std::numeric_limits<int8_t>::max());
87 lb =
static_cast<s64_t>(std::numeric_limits<int8_t>::min());
91 ub =
static_cast<s64_t>(std::numeric_limits<u_int8_t>::max());
92 lb =
static_cast<s64_t>(std::numeric_limits<u_int8_t>::min());
97 else if (SVFUtil::isa<SVFOtherType>(
type))
100 s64_t ub =
static_cast<s64_t>(std::numeric_limits<s32_t>::max());
101 s64_t lb =
static_cast<s64_t>(std::numeric_limits<s32_t>::min());
114 if (SVFUtil::isa<SVFIntegerType>(
type))
117 if (as[var->
getId()].getInterval().is_numeral())
121 int8_t signed_i8_value = as[var->
getId()].getInterval().getIntNumeral();
122 u32_t unsigned_value =
static_cast<uint8_t
>(signed_i8_value);
127 s16_t signed_i16_value = as[var->
getId()].getInterval().getIntNumeral();
128 u32_t unsigned_value =
static_cast<u16_t>(signed_i16_value);
133 s32_t signed_i32_value = as[var->
getId()].getInterval().getIntNumeral();
134 u32_t unsigned_value =
static_cast<u32_t>(signed_i32_value);
139 s64_t signed_i64_value = as[var->
getId()].getInterval().getIntNumeral();
145 assert(
false &&
"cannot support int type other than u8/16/32/64");
158 return as[var->
getId()].getInterval();
164 return getSExtValue(as, var);
170 return getZExtValue(as, var);
176 return getSExtValue(as, var);
182 return getZExtValue(as, var);
197 int8_t s8_lb =
static_cast<int8_t
>(int_lb);
198 int8_t s8_ub =
static_cast<int8_t
>(int_ub);
206 else if (dst_bits == 16)
218 else if (dst_bits == 32)
232 assert(
false &&
"cannot support dst int type other than u8/16/32");
239 return as[var->
getId()].getInterval();
249 if (rhsItem.second.isAddr())
251 for (
const auto &addr: rhsItem.second.getAddrs())
253 if (!lhsIter->second.getAddrs().contains(addr))
257 lhsIter->second.join_with(getGepObjAddress(as, getInternalID(addr), i));
269 if (rhsItem.second.isAddr())
271 for (
const auto& addr : rhsItem.second.getAddrs())
273 if (!lhsIter->second.getAddrs().contains(addr))
278 lhsIter->second.join_with(
279 getGepObjAddress(as, getInternalID(addr), i));
295 if (lhsIter->second.isAddr())
297 for (
const auto &addr: lhsIter->second.getAddrs())
299 if (!rhsItem.second.getAddrs().contains(addr))
301 lhsIter->second = rhsItem.second;
313 if (lhsIter->second.isAddr())
315 for (
const auto& addr : lhsIter->second.getAddrs())
317 if (!rhsItem.second.getAddrs().contains(addr))
319 lhsIter->second = rhsItem.second;
332 for (
const auto &addr: addrs.
getAddrs())
334 s64_t baseObj = getInternalID(addr);
335 assert(SVFUtil::isa<ObjVar>(_svfir->getGNode(baseObj)) &&
"Fail to get the base object address!");
380 if (
const SVFConstantInt* constInt = SVFUtil::dyn_cast<SVFConstantInt>(value))
381 idxLb = idxUb = constInt->getSExtValue();
384 IntervalValue idxItv = as[_svfir->getValueNode(value)].getInterval();
394 if (SVFUtil::isa<SVFPointerType>(
type))
410 if (so.empty() || idxUb >= (
APOffset)so.size() || idxLb < 0)
420 for (
u32_t idx = 0; idx < idxLb; ++idx)
426 for (
u32_t idx = idxLb; idx < idxUb; ++idx)
473 if (
const SVFConstantInt* constInt = SVFUtil::dyn_cast<SVFConstantInt>(value))
474 idxLb = idxUb = constInt->getSExtValue();
477 IntervalValue idxItv = as[_svfir->getValueNode(value)].getInterval();
487 if (SVFUtil::isa<SVFPointerType>(
type))
501 if (so.empty() || idxUb >= (
APOffset)so.size() || idxLb < 0)
538 s64_t numeral = consInt->getSExtValue();
542 as[varId] =
IntervalValue(consFP->getFPValue(), consFP->getFPValue());
543 else if (SVFUtil::isa<SVFConstantNullPtr>(obj->
getValue()))
545 else if (SVFUtil::isa<SVFGlobalValue>(obj->
getValue()))
565 initObjVar(as, SVFUtil::cast<ObjVar>(addr->
getRHSVar()));
579 IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval();
585 resVal = (lhs + rhs);
589 resVal = (lhs - rhs);
593 resVal = (lhs * rhs);
598 resVal = (lhs / rhs);
603 resVal = (lhs % rhs);
606 resVal = (lhs ^ rhs);
609 resVal = (lhs & rhs);
612 resVal = (lhs | rhs);
615 resVal = (lhs >> rhs);
618 resVal = (lhs << rhs);
621 resVal = (lhs >> rhs);
624 assert(
false &&
"undefined binary: ");
636 if (inVarToValTable(as, op0) && inVarToValTable(as, op1))
639 IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval();
647 resVal = (lhs == rhs);
653 resVal = (lhs != rhs);
659 resVal = (lhs > rhs);
665 resVal = (lhs >= rhs);
671 resVal = (lhs < rhs);
677 resVal = (lhs <= rhs);
687 assert(
false &&
"undefined compare: ");
692 else if (inVarToAddrsTable(as, op0) && inVarToAddrsTable(as, op1))
695 AbstractValue &lhs = getAddrs(as, op0), &rhs = getAddrs(as, op1);
740 if (lhs.
getAddrs().
size() == 1 && rhs.getAddrs().size() == 1)
755 if (lhs.
getAddrs().
size() == 1 && rhs.getAddrs().size() == 1)
770 if (lhs.
getAddrs().
size() == 1 && rhs.getAddrs().size() == 1)
785 if (lhs.
getAddrs().
size() == 1 && rhs.getAddrs().size() == 1)
803 assert(
false &&
"undefined compare: ");
817 for (
const auto &addr: addrs.
getAddrs())
827 for (
const auto &addr: as[lhs].getAddrs())
829 as.
store(addr, as[rhs]);
844 as[lhs] = getZExtValue(as,
copy->getRHSVar());
848 as[lhs] = getSExtValue(as,
copy->getRHSVar());
852 as[lhs] = getFPToSIntValue(as,
copy->getRHSVar());
856 as[lhs] = getFPToUIntValue(as,
copy->getRHSVar());
860 as[lhs] = getSIntToFPValue(as,
copy->getRHSVar());
864 as[lhs] = getUIntToFPValue(as,
copy->getRHSVar());
868 as[lhs] = getTruncValue(as,
copy->getRHSVar(),
copy->getLHSVar()->getType());
872 as[lhs] = getFPTruncValue(as,
copy->getRHSVar(),
copy->getLHSVar()->getType());
884 if (as[rhs].isAddr())
895 assert(
false &&
"undefined copy kind");
911 gepAddrs.
join_with(getGepObjAddress(as, rhs, i));
921 if (as[cond].getInterval().is_numeral())
923 as[res] = as[cond].getInterval().is_zero() ? as[fval] : as[tval];
928 as[res].join_with(as[fval]);
void store(u32_t addr, const AbstractValue &val)
VarToAbsValMap _varToAbsVal
Map a variable (symbol) to its abstract value.
AddrToAbsValMap _addrToAbsVal
Map a memory address to its stored abstract value.
virtual AbstractValue & load(u32_t addr)
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.
void join_with(const AbstractValue &other)
AddressValue & getAddrs()
u32_t getElementNum(const SVFType *type) const
Return element number of a type.
std::pair< const SVFVar *, const SVFType * > IdxOperandPair
const SVFType * gepSrcPointeeType() const
bool hasIntersect(const AddressValue &other)
std::pair< AddressValue::AddrSet::iterator, bool > insert(u32_t id)
AddrSet::const_iterator begin() const
NodeID getRHSVarID() const
NodeID getLHSVarID() const
SVFVar * getRHSVar() const
s64_t getIntNumeral() const
u32_t getPredicate() const
@ ICMP_SGT
signed greater than
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ ICMP_UGE
unsigned greater or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ ICMP_ULE
unsigned less or equal
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_ULT
unsigned less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_SLE
signed less or equal
NodeID getId() const
Get ID.
APOffset accumulateConstantOffset() const
Return accumulated constant offset (when accessing array or struct) if this offset is a constant.
const AccessPath::IdxOperandPairs getOffsetVarAndGepTypePairVec() const
const AccessPath & getAccessPath() const
bool isConstantOffset() const
Return TRUE if this is a constant location set.
void meet_with(const IntervalValue &other)
Return a intersected IntervalValue.
const BoundedInt & lb() const
Return the lower bound.
const BoundedInt & ub() const
Return the upper bound.
static IntervalValue top()
Create the IntervalValue [-inf, +inf].
bool isConstantStruct() const
bool isConstDataOrConstGlobal() const
const SVFValue * getValue() const
Get the reference value to this object.
bool isConstantArray() const
NodeID getOpVarID(u32_t pos) const
u32_t getOpVarNum() const
const MemObj * getMemObj() const
Return memory object.
static const Option< bool > ModelArrays
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
void handleSelect(AbstractState &es, const SelectStmt *select)
void handlePhi(AbstractState &es, const PhiStmt *phi)
IntervalValue getRangeLimitFromType(const SVFType *type)
Return the value range of Integer SVF Type, e.g. unsigned i8 Type->[0, 255], signed i8 Type->[-128,...
IntervalValue getFPTruncValue(const AbstractState &es, const SVFVar *var, const SVFType *dstType)
void handleLoad(AbstractState &es, const LoadStmt *load)
IntervalValue getFPToUIntValue(const AbstractState &es, const SVFVar *var)
static AbstractValue globalNulladdrs
void narrowAddrs(AbstractState &es, AbstractState &lhs, const AbstractState &rhs)
void initObjVar(AbstractState &as, const ObjVar *var)
Init ObjVar.
IntervalValue getByteOffset(const AbstractState &es, const GepStmt *gep)
void handleCmp(AbstractState &es, const CmpStmt *cmp)
void handleGep(AbstractState &es, const GepStmt *gep)
void handleStore(AbstractState &es, const StoreStmt *store)
AddressValue getGepObjAddress(AbstractState &es, u32_t pointer, APOffset offset)
Return the field address given a pointer points to a struct object and an offset.
IntervalValue getUIntToFPValue(const AbstractState &es, const SVFVar *var)
IntervalValue getZExtValue(const AbstractState &es, const SVFVar *var)
void handleRet(AbstractState &es, const RetPE *retPE)
IntervalValue getElementIndex(const AbstractState &es, const GepStmt *gep)
Return the offset expression of a GepStmt.
IntervalValue getFPToSIntValue(const AbstractState &es, const SVFVar *var)
void handleBinary(AbstractState &es, const BinaryOPStmt *binary)
IntervalValue getSExtValue(const AbstractState &es, const SVFVar *var)
IntervalValue getSIntToFPValue(const AbstractState &es, const SVFVar *var)
void handleCopy(AbstractState &es, const CopyStmt *copy)
void handleCall(AbstractState &es, const CallPE *callPE)
void widenAddrs(AbstractState &es, AbstractState &lhs, const AbstractState &rhs)
IntervalValue getTruncValue(const AbstractState &es, const SVFVar *var, const SVFType *dstType)
void handleAddr(AbstractState &es, const AddrStmt *addr)
u32_t getByteSize() const
virtual const SVFType * getType() const
Return type of the value.
const SVFVar * getTrueValue() const
const SVFVar * getCondition() const
const SVFVar * getFalseValue() const
std::vector< u32_t > & getFlattenedElemIdxVec()
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis.
const StInfo * getTypeInfo(const SVFType *T) const
Get struct info.
const SVFType * getFlatternedElemType(const SVFType *baseType, u32_t flatten_idx)
Return the type of a flattened element given a flattened index.