35 using namespace SVFUtil;
39 return *
this == other;
44 size_t h = getVarToVal().size() * 2;
46 for (
const auto &t: getVarToVal())
48 h ^= hf(t.first) + 0x9e3779b9 + (h << 6) + (h >> 2);
50 size_t h2 = getLocToVal().size() * 2;
51 for (
const auto &t: getLocToVal())
53 h2 ^= hf(t.first) + 0x9e3779b9 + (h2 << 6) + (h2 >> 2);
56 return pairH({h, h2});
67 if (it->second.isInterval() && other.
_varToAbsVal.at(key).isInterval())
68 it->second.getInterval().widen_with(other.
_varToAbsVal.at(key).getInterval());
74 if (it->second.isInterval() && other.
_addrToAbsVal.at(key).isInterval())
75 it->second.getInterval().widen_with(other.
_addrToAbsVal.at(key).getInterval());
87 if (it->second.isInterval() && other.
_varToAbsVal.at(key).isInterval())
88 it->second.getInterval().narrow_with(other.
_varToAbsVal.at(key).getInterval());
94 if (it->second.isInterval() && other.
_addrToAbsVal.at(key).isInterval())
95 it->second.getInterval().narrow_with(other.
_addrToAbsVal.at(key).getInterval());
106 auto key = it->first;
107 auto oit = _varToAbsVal.find(key);
108 if (oit != _varToAbsVal.end())
110 oit->second.join_with(it->second);
114 _varToAbsVal.emplace(key, it->second);
119 auto key = it->first;
120 auto oit = _addrToAbsVal.find(key);
121 if (oit != _addrToAbsVal.end())
123 oit->second.join_with(it->second);
127 _addrToAbsVal.emplace(key, it->second);
137 auto key = it->first;
138 auto oit = _varToAbsVal.find(key);
139 if (oit != _varToAbsVal.end())
141 oit->second.meet_with(it->second);
146 auto key = it->first;
147 auto oit = _addrToAbsVal.find(key);
148 if (oit != _addrToAbsVal.end())
150 oit->second.meet_with(it->second);
166 for (
const auto& addr : addrs.
getAddrs())
169 assert(SVFUtil::isa<ObjVar>(
PAG::getPAG()->getGNode(baseObj)) &&
"Fail to get the base object address!");
193 s64_t numeral = consInt->getSExtValue();
198 (*this)[varId] =
IntervalValue(consFP->getFPValue(), consFP->getFPValue());
200 else if (SVFUtil::isa<SVFConstantNullPtr>(obj->
getValue()))
204 else if (SVFUtil::isa<SVFGlobalValue>(obj->
getValue()))
251 if (
const SVFConstantInt* constInt = SVFUtil::dyn_cast<SVFConstantInt>(value))
252 idxLb = idxUb = constInt->getSExtValue();
266 if (SVFUtil::isa<SVFPointerType>(
type))
278 if (so.empty() || idxUb >= (
APOffset)so.size() || idxLb < 0)
320 if (SVFUtil::isa<SVFArrayType>(idxOperandType) || SVFUtil::isa<SVFPointerType>(idxOperandType))
322 u32_t elemByteSize = 1;
323 if (
const SVFArrayType* arrOperandType = SVFUtil::dyn_cast<SVFArrayType>(idxOperandType))
324 elemByteSize = arrOperandType->getTypeOfElement()->getByteSize();
325 else if (SVFUtil::isa<SVFPointerType>(idxOperandType))
328 assert(
false &&
"idxOperandType must be ArrType or PtrType");
334 ? op->getSExtValue() * elemByteSize
361 else if (
const SVFStructType* structOperandType = SVFUtil::dyn_cast<SVFStructType>(idxOperandType))
367 assert(
false &&
"gep type pair only support arr/ptr/struct");
376 for (
auto addr : (*
this)[varId].getAddrs())
385 for (
auto addr : (*
this)[varId].getAddrs())
394 u32_t fieldWidth = 20;
396 std::vector<std::pair<u32_t, AbstractValue>> varToAbsValVec(_varToAbsVal.begin(), _varToAbsVal.end());
397 std::sort(varToAbsValVec.begin(), varToAbsValVec.end(), [](
const auto &
a,
const auto &
b)
399 return a.first < b.first;
401 for (
const auto &
item: varToAbsValVec)
403 SVFUtil::outs() << std::left << std::setw(fieldWidth) << (
"Var" + std::to_string(
item.first));
404 if (
item.second.isInterval())
408 else if (
item.second.isAddr())
412 for (
const auto& addr:
item.second.getAddrs())
415 if (i <
item.second.getAddrs().size())
432 std::vector<std::pair<u32_t, AbstractValue>> addrToAbsValVec(_addrToAbsVal.begin(), _addrToAbsVal.end());
433 std::sort(addrToAbsValVec.begin(), addrToAbsValVec.end(), [](
const auto &
a,
const auto &
b)
435 return a.first < b.first;
438 for (
const auto&
item: addrToAbsValVec)
440 std::ostringstream oss;
442 SVFUtil::outs() << std::left << std::setw(fieldWidth) << oss.str();
443 if (
item.second.isInterval())
447 else if (
item.second.isAddr())
451 for (
const auto& addr:
item.second.getAddrs())
454 if (i <
item.second.getAddrs().size())
470 SVFUtil::outs() <<
"-----------------------------------------\n";
476 if (inVarToAddrsTable(
id))
484 return SVFUtil::dyn_cast<ObjVar>(svfir->
getGNode(addr_id))->getMemObj()->getType();
497 if (
const ObjVar* objvar = SVFUtil::dyn_cast<ObjVar>(addr->
getRHSVar()))
500 if (objvar->getMemObj()->isConstantByteSize())
502 u32_t sz = objvar->getMemObj()->getByteSizeOfObj();
508 const std::vector<SVFValue*>& sizes = addr->
getArrSize();
510 u32_t elementSize = 1;
511 u64_t res = elementSize;
525 assert (
false &&
"Addr rhs value is not ObjVar");
u32_t getAllocaInstByteSize(const AddrStmt *addr)
void printAbstractState() const
void joinWith(const AbstractState &other)
domain join with other, important! other widen this.
IntervalValue getElementIndex(const GepStmt *gep)
bool equals(const AbstractState &other) const
VarToAbsValMap _varToAbsVal
Map a variable (symbol) to its abstract value.
AddrToAbsValMap _addrToAbsVal
Map a memory address to its stored abstract value.
const SVFType * getPointeeElement(NodeID id)
IntervalValue getByteOffset(const GepStmt *gep)
AbstractValue loadValue(NodeID varId)
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.
AbstractState narrowing(const AbstractState &other)
domain narrow with other, and return the narrowed domain
static u32_t getInternalID(u32_t idx)
Return the internal index if idx is an address otherwise return the value of idx.
void storeValue(NodeID varId, AbstractValue val)
void meetWith(const AbstractState &other)
domain meet with other, important! other widen this.
AddressValue getGepObjAddrs(u32_t pointer, IntervalValue offset)
void initObjVar(ObjVar *objVar)
AbstractState widening(const AbstractState &other)
domain widen with other, and return the widened domain
void join_with(const AbstractValue &other)
AddressValue & getAddrs()
u32_t getStructFieldOffset(const SVFVar *idxOperandVar, const SVFStructType *idxOperandType) const
Return byte offset from the beginning of the structure to the field where it is located for struct ty...
u32_t getElementNum(const SVFType *type) const
Return element number of a type.
std::pair< const SVFVar *, const SVFType * > IdxOperandPair
const SVFType * gepSrcPointeeType() const
const std::vector< SVFValue * > & getArrSize() const
std::pair< AddressValue::AddrSet::iterator, bool > insert(u32_t id)
SVFVar * getRHSVar() const
s64_t getIntNumeral() const
NodeType * getGNode(NodeID id) const
Get a node.
APOffset accumulateConstantOffset() const
Return accumulated constant offset (when accessing array or struct) if this offset is a constant.
APOffset accumulateConstantByteOffset() const
const AccessPath::IdxOperandPairs getOffsetVarAndGepTypePairVec() const
const AccessPath & getAccessPath() const
bool isConstantOffset() const
Return TRUE if this is a constant location set.
NodeID getValueNode(const SVFValue *V)
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
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.
NodeID getId() const
Get ID.
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
NodeID getGepObjVar(const MemObj *obj, const APOffset &ap)
Get a field SVFIR Object node according to base mem obj and offset.
u32_t getByteSize() const
const SVFValue * getValue() const
Get/has methods of the components.
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.
std::ostream & outs()
Overwrite llvm::outs()
provide extra hash function for std::pair handling