Static Value-Flow Analysis
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
SVF::AccessPath Class Reference

#include <AccessPath.h>

Public Types

enum  LSRelation {
  NonOverlap , Overlap , Subset , Superset ,
  Same
}
 
typedef std::pair< const SVFVar *, const SVFType * > IdxOperandPair
 
typedef std::vector< IdxOperandPairIdxOperandPairs
 

Public Member Functions

 AccessPath (APOffset o=0, const SVFType *srcTy=nullptr)
 Constructor.
 
 AccessPath (const AccessPath &ap)
 Copy Constructor.
 
 ~AccessPath ()
 
AccessPath operator+ (const AccessPath &rhs) const
 Overload operators.
 
bool operator< (const AccessPath &rhs) const
 
const AccessPathoperator= (const AccessPath &rhs)
 
bool operator== (const AccessPath &rhs) const
 
APOffset getConstantStructFldIdx () const
 Get methods.
 
void setFldIdx (APOffset idx)
 
const IdxOperandPairsgetIdxOperandPairVec () const
 
const SVFTypegepSrcPointeeType () const
 
APOffset computeConstantByteOffset () const
 
APOffset computeConstantOffset () const
 For example,.
 
u32_t getElementNum (const SVFType *type) const
 Return element number of a type.
 
bool addOffsetVarAndGepTypePair (const SVFVar *var, const SVFType *gepIterType)
 
bool isConstantOffset () const
 Return TRUE if this is a constant location set.
 
bool intersects (const AccessPath &RHS) const
 Return TRUE if we share any location in common with RHS.
 
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 type.
 
std::string dump () const
 Dump location set.
 

Private Member Functions

LSRelation checkRelation (const AccessPath &LHS, const AccessPath &RHS)
 Check relations of two location sets.
 
NodeBS computeAllLocations () const
 Compute all possible locations according to offset and number-stride pairs.
 

Private Attributes

APOffset fldIdx
 Accumulated Constant Offsets.
 
IdxOperandPairs idxOperandPairs
 a vector of actual offset in the form of <SVF Var, iterator type>
 
const SVFTypegepPointeeType
 

Friends

class SymbolTableInfo
 
class SVFIRWriter
 
class SVFIRReader
 

Detailed Description

Definition at line 52 of file AccessPath.h.

Member Typedef Documentation

◆ IdxOperandPair

Definition at line 64 of file AccessPath.h.

◆ IdxOperandPairs

Definition at line 65 of file AccessPath.h.

Member Enumeration Documentation

◆ LSRelation

Enumerator
NonOverlap 
Overlap 
Subset 
Superset 
Same 

Definition at line 59 of file AccessPath.h.

Constructor & Destructor Documentation

◆ AccessPath() [1/2]

SVF::AccessPath::AccessPath ( APOffset  o = 0,
const SVFType srcTy = nullptr 
)
inline

Constructor.

Definition at line 68 of file AccessPath.h.

const SVFType * gepPointeeType
Definition AccessPath.h:177
APOffset fldIdx
Accumulated Constant Offsets.
Definition AccessPath.h:175
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74

◆ AccessPath() [2/2]

SVF::AccessPath::AccessPath ( const AccessPath ap)
inline

Copy Constructor.

Definition at line 71 of file AccessPath.h.

72 : fldIdx(ap.fldIdx),
73 idxOperandPairs(ap.getIdxOperandPairVec()),
74 gepPointeeType(ap.gepSrcPointeeType())
75 {
76 }
IdxOperandPairs idxOperandPairs
a vector of actual offset in the form of <SVF Var, iterator type>
Definition AccessPath.h:176

◆ ~AccessPath()

SVF::AccessPath::~AccessPath ( )
inline

Definition at line 78 of file AccessPath.h.

78{}

Member Function Documentation

◆ addOffsetVarAndGepTypePair()

bool AccessPath::addOffsetVarAndGepTypePair ( const SVFVar var,
const SVFType gepIterType 
)

Add offset value to vector offsetVarAndGepTypePairs

Definition at line 42 of file AccessPath.cpp.

43{
44 idxOperandPairs.emplace_back(var, gepIterType);
45 return true;
46}

◆ checkRelation()

SVF::AccessPath::LSRelation AccessPath::checkRelation ( const AccessPath LHS,
const AccessPath RHS 
)
private

Check relations of two location sets.

Definition at line 310 of file AccessPath.cpp.

311{
312 NodeBS lhsLocations = LHS.computeAllLocations();
313 NodeBS rhsLocations = RHS.computeAllLocations();
314 if (lhsLocations.intersects(rhsLocations))
315 {
317 return Same;
318 else if (lhsLocations.contains(rhsLocations))
319 return Superset;
320 else if (rhsLocations.contains(lhsLocations))
321 return Subset;
322 else
323 return Overlap;
324 }
325 else
326 {
327 return NonOverlap;
328 }
329}

◆ computeAllLocations()

NodeBS AccessPath::computeAllLocations ( ) const
private

Compute all possible locations according to offset and number-stride pairs.

Compute all possible locations according to offset and number-stride pairs.

Definition at line 268 of file AccessPath.cpp.

269{
272 return result;
273}
APOffset getConstantStructFldIdx() const
Get methods.
Definition AccessPath.h:100
void set(unsigned Idx)

◆ computeConstantByteOffset()

APOffset AccessPath::computeConstantByteOffset ( ) const

Computes the total constant byte offset of an access path. This function iterates over the offset-variable-type pairs in reverse order, accumulating the total byte offset for constant offsets. For each pair, it retrieves the corresponding SVFValue and determines the type of offset (whether it's an array, pointer, or structure). If the offset corresponds to a structure, it further resolves the actual element type based on the offset value. It then multiplies the offset value by the size of the type to compute the byte offset. This is used to handle composite types where offsets are derived from the type's internal structure, such as arrays or structures with fields of various types and sizes. The function asserts that the access path must have a constant offset, and it is intended to be used when the offset is known to be constant at compile time.

Returns
APOffset representing the computed total constant byte offset. e.g. GepStmt* gep = [i32*4], 2 APOffset byteOffset = gep->accumulateConstantByteOffset(); byteOffset should be 8 since i32 is 4 bytes and index is 2.

Return accumulated constant offset

"value" is the offset variable (must be a constant) "type" is the location where we want to compute offset Given a vector and elem byte size: [(value1,type1), (value2,type2), (value3,type3)], bytesize totalConstByteOffset = ByteOffset(value1,type1) * ByteOffset(value2,type2) + ByteOffset(value3,type3) For a pointer type (e.g., t1 is PointerType), we will retrieve the pointee type and times the offset, i.e., getElementNum(t1) X off1

For example, there is struct DEST{int a, char b[10], int c[5]} (1) c = getelementptr inbounds struct.DEST, struct.DEST* arr, i32 0, i32 2

for (1) offsetVarAndGepTypePairs.size() = 2 i = 0, type: struct.DEST*, PtrType, op = 0 i = 1, type: struct.DEST, StructType, op = 2 for (2) offsetVarAndGepTypePairs.size() = 2 i = 0, type: [10 x i8]*, PtrType, op = 0 i = 1, type: [10 x i8], ArrType, op = 8

if offsetVarAndGepTypePairs[i].second is nullptr, it means GepStmt comes from external API, this GepStmt is assigned in SVFIRExtAPI.cpp at SVFIRBuilder::getBaseTypeAndFlattenedFields ls.addOffsetVarAndGepTypePair()

for (2) i = 1, arrType: [10 x i8], type2 = i8

for (1) i = 0, ptrType: struct.DEST*, type2: struct.DEST for (2) i = 0, ptrType: [10 x i8]*, type2 = [10 x i8]

for (1) structType: struct.DEST structField = 0, flattenIdx = 0, type2: int structField = 1, flattenIdx = 1, type2: char[10] structField = 2, flattenIdx = 11, type2: int[5]

for (2) i = 0, op: 0, type: [10 x i8]*(Ptr), type2: [10 x i8](Arr) i = 1, op: 8, type: [10 x i8](Arr), type2: i8

Definition at line 124 of file AccessPath.cpp.

125{
126 assert(isConstantOffset() && "not a constant offset");
127
129 for(int i = idxOperandPairs.size() - 1; i >= 0; i--)
130 {
133 // (2) %arrayidx = getelementptr inbounds [10 x i8], [10 x i8]* %b, i64 0, i64 8
134 const SVFVar* var = idxOperandPairs[i].first;
141 const SVFType* type = idxOperandPairs[i].second;
145 assert(type && "this GepStmt comes from ExternalAPI cannot call this api");
146 const SVFType* type2 = type;
147 if (const SVFArrayType* arrType = SVFUtil::dyn_cast<SVFArrayType>(type))
148 {
150 type2 = arrType->getTypeOfElement();
151 }
152 else if (SVFUtil::isa<SVFPointerType>(type))
153 {
157 }
158
159 const ConstantIntValVar* op = SVFUtil::dyn_cast<ConstantIntValVar>(var);
160 if (const SVFStructType* structType = SVFUtil::dyn_cast<SVFStructType>(type))
161 {
166 for (u32_t structField = 0; structField < (u32_t)op->getSExtValue(); ++structField)
167 {
168 u32_t flattenIdx = structType->getTypeInfo()->getFlattenedFieldIdxVec()[structField];
169 type2 = structType->getTypeInfo()->getOriginalElemType(flattenIdx);
170 totalConstOffset += type2->getByteSize();
171 }
172 }
173 else
174 {
177 totalConstOffset += op->getSExtValue() * type2->getByteSize();
178 }
179 }
181 return totalConstOffset;
182}
unsigned u32_t
Definition CommandLine.h:18
newitem type
Definition cJSON.cpp:2739
bool isConstantOffset() const
Return TRUE if this is a constant location set.
const SVFType * gepSrcPointeeType() const
Definition AccessPath.h:112
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:38
s64_t APOffset
Definition GeneralType.h:60
unsigned u32_t
Definition GeneralType.h:46

◆ computeConstantOffset()

APOffset AccessPath::computeConstantOffset ( ) const

For example,.

Return accumulated constant offset given OffsetVarVec compard to computeConstantByteOffset, it is field offset rather than byte offset e.g. GepStmt* gep = [i32*4], 2 APOffset byteOffset = gep->computeConstantOffset(); byteOffset should be 2 since it is field offset.

Return accumulated constant offset

"value" is the offset variable (must be a constant) "type" is the location where we want to compute offset Given a vector: [(value1,type1), (value2,type2), (value3,type3)] totalConstOffset = flattenOffset(value1,type1) * flattenOffset(value2,type2) + flattenOffset(value3,type3) For a pointer type (e.g., t1 is PointerType), we will retrieve the pointee type and times the offset, i.e., getElementNum(t1) X off1 %5 = getelementptr inbounds struct.Student, struct.Student* %4, i64 1 value1: i64 1 type1: struct.Student* computeConstantOffset = 32 %6 = getelementptr inbounds struct.Student, struct.Student* %5, i32 0, i32 1 value1: i32 0 type1: struct.Student* value2: i32 1 type2: struct.Student = type { struct.inner, [10 x [3 x i8]] } computeConstantOffset = 2 %7 = getelementptr inbounds [10 x [3 x i8]], [10 x [3 x i8]]* %6, i64 0, i64 3 value1: i64 0 type1: [10 x [3 x i8]]* value2: i64 3 type2: [10 x [3 x i8]] computeConstantOffset = 9 %8 = getelementptr inbounds [3 x i8], [3 x i8]* %7, i64 0, i64 2 value1: i64 0 type1: [3 x i8]* value2: i64 2 type2: [3 x i8] computeConstantOffset = 2

Definition at line 212 of file AccessPath.cpp.

213{
214
215 assert(isConstantOffset() && "not a constant offset");
216
218 //After the model-const and model-array options are turned on,
219 // the gepstmt offset generated by the array on the global
220 // node will be saved in getConstantStructFldIdx
221 if (idxOperandPairs.size() == 0)
223 for(int i = idxOperandPairs.size() - 1; i >= 0; i--)
224 {
225 const SVFVar* var = idxOperandPairs[i].first;
226 const SVFType* type = idxOperandPairs[i].second;
227 assert(SVFUtil::isa<ConstantIntValVar>(var) && "not a constant offset?");
228 s64_t constOffset = SVFUtil::dyn_cast<ConstantIntValVar>(var)->getSExtValue();
229
230 if(type==nullptr)
231 {
233 continue;
234 }
235
236 if(SVFUtil::isa<SVFPointerType>(type))
238 else
239 {
241 if (offset >= 0)
242 {
243 const std::vector<u32_t>& so = SymbolTableInfo::SymbolInfo()->getTypeInfo(type)->getFlattenedElemIdxVec();
244 // if offset is larger than the size of getFlattenedElemIdxVec (overflow)
245 // set offset the last index of getFlattenedElemIdxVec to avoid assertion
246 if (offset >= (APOffset)so.size())
247 {
248 SVFUtil::errs() << "It is an overflow access, hence it is the last idx\n";
249 offset = so.size() - 1;
250 }
251 else
252 {
253
254 }
255
258 offset);
260 }
261 }
262 }
263 return totalConstOffset;
264}
buffer offset
Definition cJSON.cpp:1113
u32_t getElementNum(const SVFType *type) const
Return element number of a type.
std::vector< u32_t > & getFlattenedElemIdxVec()
Definition SVFType.h:98
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 & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:56
signed long long s64_t
Definition GeneralType.h:49

◆ dump()

std::string AccessPath::dump ( ) const

Dump location set.

Definition at line 332 of file AccessPath.cpp.

333{
334 std::string str;
335 std::stringstream rawstr(str);
336
337 rawstr << "AccessPath\tField_Index: " << getConstantStructFldIdx();
338 rawstr << ",\tNum-Stride: {";
340 IdxOperandPairs::const_iterator it = vec.begin();
341 IdxOperandPairs::const_iterator eit = vec.end();
342 for (; it != eit; ++it)
343 {
344 const SVFType* ty = it->second;
345 rawstr << " (Svf var: " << it->first->toString() << ", Iter type: " << *ty << ")";
346 }
347 rawstr << " }\n";
348 return rawstr.str();
349}
std::vector< IdxOperandPair > IdxOperandPairs
Definition AccessPath.h:65
const IdxOperandPairs & getIdxOperandPairVec() const
Definition AccessPath.h:108
std::string toString() const

◆ gepSrcPointeeType()

const SVFType * SVF::AccessPath::gepSrcPointeeType ( ) const
inline

Definition at line 112 of file AccessPath.h.

113 {
114 return gepPointeeType;
115 }

◆ getConstantStructFldIdx()

APOffset SVF::AccessPath::getConstantStructFldIdx ( ) const
inline

Get methods.

Definition at line 100 of file AccessPath.h.

101 {
102 return fldIdx;
103 }

◆ getElementNum()

u32_t AccessPath::getElementNum ( const SVFType type) const

Return element number of a type.

Return element number of a type (1) StructType or Array, return flattened number elements. (2) Pointer type, return max field limit (3) Non-pointer SingleValueType or Function Type, return 1

Definition at line 63 of file AccessPath.cpp.

64{
65 if (SVFUtil::isa<SVFArrayType, SVFStructType>(type))
66 {
68 }
69 else if (type->isPointerTy())
70 {
71 // if type is a pointer, should be like:
72 // %2 = getelementptr inbounds i32*, i32** %1, ...
73 // where gepSrcPointee is of pointer type (i32*).
74 // this can be transformed to:
75 // %2 = getelementptr inbounds [N x i32], [N x i32]* %1, ...
76 // However, we do not know N without context information. int** implies non-contiguous blocks of memory
77 // In this case, we conservatively return max field limit
79 }
80 else if (type->isSingleValueType() || SVFUtil::isa<SVFFunctionType>(type))
81 {
82 return 1;
83 }
84 else
85 {
86 SVFUtil::outs() << "GepIter Type" << *type << "\n";
87 assert(false && "What other types for this gep?");
88 abort();
89 }
90}
u32_t getNumOfFlattenElements(const SVFType *T)
Number of flattened elements of an array or struct.
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50

◆ getIdxOperandPairVec()

const IdxOperandPairs & SVF::AccessPath::getIdxOperandPairVec ( ) const
inline

Definition at line 108 of file AccessPath.h.

109 {
110 return idxOperandPairs;
111 }

◆ getStructFieldOffset()

u32_t AccessPath::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 type.

Return byte offset from the beginning of the structure to the field where it is located for struct type

Definition at line 98 of file AccessPath.cpp.

99{
101 if (const ConstantIntValVar *op = SVFUtil::dyn_cast<ConstantIntValVar>(idxOperandVar))
102 {
103 for (u32_t structField = 0; structField < (u32_t) op->getSExtValue(); ++structField)
104 {
105 u32_t flattenIdx = idxOperandType->getTypeInfo()->getFlattenedFieldIdxVec()[structField];
106 structByteOffset += idxOperandType->getTypeInfo()->getOriginalElemType(flattenIdx)->getByteSize();
107 }
108 return structByteOffset;
109 }
110 else
111 {
112 assert(false && "struct type can only pair with constant idx");
113 abort();
114 }
115}

◆ intersects()

bool SVF::AccessPath::intersects ( const AccessPath RHS) const
inline

Return TRUE if we share any location in common with RHS.

Definition at line 156 of file AccessPath.h.

157 {
158 return computeAllLocations().intersects(RHS.computeAllLocations());
159 }
NodeBS computeAllLocations() const
Compute all possible locations according to offset and number-stride pairs.
bool intersects(const SparseBitVector< ElementSize > *RHS) const

◆ isConstantOffset()

bool AccessPath::isConstantOffset ( ) const

Return TRUE if this is a constant location set.

Return true if all offset values are constants.

Definition at line 49 of file AccessPath.cpp.

50{
51 for(auto it : idxOperandPairs)
52 {
53 if(SVFUtil::isa<ConstantIntValVar>(it.first) == false)
54 return false;
55 }
56 return true;
57}

◆ operator+()

AccessPath AccessPath::operator+ ( const AccessPath rhs) const

Overload operators.

Definition at line 275 of file AccessPath.cpp.

276{
277 assert(gepPointeeType == rhs.gepSrcPointeeType() && "source element type not match");
278 AccessPath ap(rhs);
279 ap.fldIdx += getConstantStructFldIdx();
280 for (auto &p : ap.getIdxOperandPairVec())
282
283 return ap;
284}
cJSON * p
Definition cJSON.cpp:2559
bool addOffsetVarAndGepTypePair(const SVFVar *var, const SVFType *gepIterType)

◆ operator<()

bool AccessPath::operator< ( const AccessPath rhs) const

Definition at line 286 of file AccessPath.cpp.

287{
288 if (fldIdx != rhs.fldIdx)
289 return (fldIdx < rhs.fldIdx);
290 else
291 {
293 const IdxOperandPairs& rhsPairVec = rhs.getIdxOperandPairVec();
294 if (pairVec.size() != rhsPairVec.size())
295 return (pairVec.size() < rhsPairVec.size());
296 else
297 {
298 IdxOperandPairs::const_iterator it = pairVec.begin();
299 IdxOperandPairs::const_iterator rhsIt = rhsPairVec.begin();
300 for (; it != pairVec.end() && rhsIt != rhsPairVec.end(); ++it, ++rhsIt)
301 {
302 return (*it) < (*rhsIt);
303 }
304
305 return false;
306 }
307 }
308}

◆ operator=()

const AccessPath & SVF::AccessPath::operator= ( const AccessPath rhs)
inline

Definition at line 84 of file AccessPath.h.

85 {
86 fldIdx = rhs.fldIdx;
87 idxOperandPairs = rhs.getIdxOperandPairVec();
88 gepPointeeType = rhs.gepPointeeType;
89 return *this;
90 }

◆ operator==()

bool SVF::AccessPath::operator== ( const AccessPath rhs) const
inline

Definition at line 91 of file AccessPath.h.

92 {
93 return this->fldIdx == rhs.fldIdx &&
94 this->idxOperandPairs == rhs.idxOperandPairs && this->gepPointeeType == rhs.gepPointeeType;
95 }

◆ setFldIdx()

void SVF::AccessPath::setFldIdx ( APOffset  idx)
inline

Definition at line 104 of file AccessPath.h.

105 {
106 fldIdx = idx;
107 }

Friends And Related Symbol Documentation

◆ SVFIRReader

Definition at line 56 of file AccessPath.h.

◆ SVFIRWriter

Definition at line 55 of file AccessPath.h.

◆ SymbolTableInfo

Definition at line 54 of file AccessPath.h.

Member Data Documentation

◆ fldIdx

APOffset SVF::AccessPath::fldIdx
private

Accumulated Constant Offsets.

Definition at line 175 of file AccessPath.h.

◆ gepPointeeType

const SVFType* SVF::AccessPath::gepPointeeType
private

Definition at line 177 of file AccessPath.h.

◆ idxOperandPairs

IdxOperandPairs SVF::AccessPath::idxOperandPairs
private

a vector of actual offset in the form of <SVF Var, iterator type>

Definition at line 176 of file AccessPath.h.


The documentation for this class was generated from the following files: