svf-tools 1.0.674 → 1.0.676
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/svf/include/Graphs/ConsGEdge.h +1 -1
- package/svf/include/MemoryModel/LocationSet.h +3 -3
- package/svf/include/SVFIR/SVFStatements.h +2 -2
- package/svf/include/SVFIR/SVFVariables.h +5 -5
- package/svf/lib/MemoryModel/LocationSet.cpp +9 -9
- package/svf/lib/SABER/SaberSVFGBuilder.cpp +11 -15
- package/svf/lib/SVFIR/SVFIR.cpp +2 -2
- package/svf/lib/SVFIR/SVFVariables.cpp +1 -1
- package/svf/lib/SVFIR/SymbolTableInfo.cpp +3 -3
- package/svf-llvm/lib/SVFIRBuilder.cpp +16 -10
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
|
|
43
43
|
<br />
|
|
44
44
|
|
|
45
|
-
#### We are looking for self-motivated PhD students and we welcome industry collaboration/sponsorship to improve SVF (Please contact
|
|
45
|
+
#### We are looking for self-motivated PhD students and we welcome industry collaboration/sponsorship to improve SVF (Please contact y.sui@unsw.edu.au if you are interested)
|
|
46
46
|
|
|
47
47
|
<br />
|
|
48
48
|
<p>We release SVF source code in the hope of benefiting others. You are kindly asked to acknowledge usage of the tool by citing some of our publications listed http://svf-tools.github.io/SVF, especially the following two: </p>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.676",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -92,7 +92,7 @@ public:
|
|
|
92
92
|
|
|
93
93
|
/// Get methods
|
|
94
94
|
//@{
|
|
95
|
-
inline s32_t
|
|
95
|
+
inline s32_t getConstantFieldIdx() const
|
|
96
96
|
{
|
|
97
97
|
return fldIdx;
|
|
98
98
|
}
|
|
@@ -107,7 +107,7 @@ public:
|
|
|
107
107
|
//@}
|
|
108
108
|
|
|
109
109
|
/// Return accumulated constant offset given OffsetVarVec
|
|
110
|
-
s32_t
|
|
110
|
+
s32_t computeConstantOffset() const;
|
|
111
111
|
|
|
112
112
|
/// Return element number of a type.
|
|
113
113
|
u32_t getElementNum(const SVFType* type) const;
|
|
@@ -147,7 +147,7 @@ template <> struct std::hash<SVF::LocationSet>
|
|
|
147
147
|
{
|
|
148
148
|
SVF::Hash<std::pair<SVF::NodeID, SVF::NodeID>> h;
|
|
149
149
|
std::hash<SVF::LocationSet::OffsetVarAndGepTypePairs> v;
|
|
150
|
-
return h(std::make_pair(ls.
|
|
150
|
+
return h(std::make_pair(ls.getConstantFieldIdx(), v(ls.getOffsetVarAndGepTypePairVec())));
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
153
|
|
|
@@ -456,13 +456,13 @@ public:
|
|
|
456
456
|
/// Return accumulated constant offset (when accessing array or struct) if this offset is a constant.
|
|
457
457
|
inline s32_t accumulateConstantOffset() const
|
|
458
458
|
{
|
|
459
|
-
return getLocationSet().
|
|
459
|
+
return getLocationSet().computeConstantOffset();
|
|
460
460
|
}
|
|
461
461
|
/// Field index of the gep statement if it access the field of a struct
|
|
462
462
|
inline s32_t getConstantFieldIdx() const
|
|
463
463
|
{
|
|
464
464
|
assert(isVariantFieldGep()==false && "Can't retrieve the LocationSet if using a variable field index (pointer arithmetic) for struct field access ");
|
|
465
|
-
return getLocationSet().
|
|
465
|
+
return getLocationSet().getConstantFieldIdx();
|
|
466
466
|
}
|
|
467
467
|
/// Gep statement with a variant field index (pointer arithmetic) for struct field access
|
|
468
468
|
inline bool isVariantFieldGep() const
|
|
@@ -399,7 +399,7 @@ public:
|
|
|
399
399
|
/// offset of the base value variable
|
|
400
400
|
inline s32_t getConstantFieldIdx() const
|
|
401
401
|
{
|
|
402
|
-
return ls.
|
|
402
|
+
return ls.getConstantFieldIdx();
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
/// Return name of a LLVM value
|
|
@@ -466,7 +466,7 @@ public:
|
|
|
466
466
|
/// offset of the mem object
|
|
467
467
|
inline s32_t getConstantFieldIdx() const
|
|
468
468
|
{
|
|
469
|
-
return ls.
|
|
469
|
+
return ls.getConstantFieldIdx();
|
|
470
470
|
}
|
|
471
471
|
|
|
472
472
|
/// Set the base object from which this GEP node came from.
|
|
@@ -484,15 +484,15 @@ public:
|
|
|
484
484
|
/// Return the type of this gep object
|
|
485
485
|
inline virtual const SVFType* getType() const
|
|
486
486
|
{
|
|
487
|
-
return SymbolTableInfo::SymbolInfo()->getFlatternedElemType(mem->getType(), ls.
|
|
487
|
+
return SymbolTableInfo::SymbolInfo()->getFlatternedElemType(mem->getType(), ls.getConstantFieldIdx());
|
|
488
488
|
}
|
|
489
489
|
|
|
490
490
|
/// Return name of a LLVM value
|
|
491
491
|
inline const std::string getValueName() const
|
|
492
492
|
{
|
|
493
493
|
if (value)
|
|
494
|
-
return value->getName() + "_" + std::to_string(ls.
|
|
495
|
-
return "offset_" + std::to_string(ls.
|
|
494
|
+
return value->getName() + "_" + std::to_string(ls.getConstantFieldIdx());
|
|
495
|
+
return "offset_" + std::to_string(ls.getConstantFieldIdx());
|
|
496
496
|
}
|
|
497
497
|
|
|
498
498
|
virtual const std::string toString() const;
|
|
@@ -102,26 +102,26 @@ u32_t LocationSet::getElementNum(const SVFType* type) const
|
|
|
102
102
|
|
|
103
103
|
/// %5 = getelementptr inbounds %struct.Student, %struct.Student* %4, i64 1
|
|
104
104
|
/// value1: i64 1 type1: %struct.Student*
|
|
105
|
-
///
|
|
105
|
+
/// computeConstantOffset = 32
|
|
106
106
|
/// %6 = getelementptr inbounds %struct.Student, %struct.Student* %5, i32 0, i32 1
|
|
107
107
|
/// value1: i32 0 type1: %struct.Student*
|
|
108
108
|
/// value2: i32 1 type2: %struct.Student = type { %struct.inner, [10 x [3 x i8]] }
|
|
109
|
-
///
|
|
109
|
+
/// computeConstantOffset = 2
|
|
110
110
|
/// %7 = getelementptr inbounds [10 x [3 x i8]], [10 x [3 x i8]]* %6, i64 0, i64 3
|
|
111
111
|
/// value1: i64 0 type1: [10 x [3 x i8]]*
|
|
112
112
|
/// value2: i64 3 type2: [10 x [3 x i8]]
|
|
113
|
-
///
|
|
113
|
+
/// computeConstantOffset = 9
|
|
114
114
|
/// %8 = getelementptr inbounds [3 x i8], [3 x i8]* %7, i64 0, i64 2
|
|
115
115
|
/// value1: i64 0 type1: [3 x i8]*
|
|
116
116
|
/// value2: i64 2 type2: [3 x i8]
|
|
117
|
-
///
|
|
118
|
-
s32_t LocationSet::
|
|
117
|
+
/// computeConstantOffset = 2
|
|
118
|
+
s32_t LocationSet::computeConstantOffset() const
|
|
119
119
|
{
|
|
120
120
|
|
|
121
121
|
assert(isConstantOffset() && "not a constant offset");
|
|
122
122
|
|
|
123
123
|
if(offsetVarAndGepTypePairs.empty())
|
|
124
|
-
return
|
|
124
|
+
return getConstantFieldIdx();
|
|
125
125
|
|
|
126
126
|
s32_t totalConstOffset = 0;
|
|
127
127
|
for(int i = offsetVarAndGepTypePairs.size() - 1; i >= 0; i--)
|
|
@@ -153,14 +153,14 @@ s32_t LocationSet::accumulateConstantOffset() const
|
|
|
153
153
|
NodeBS LocationSet::computeAllLocations() const
|
|
154
154
|
{
|
|
155
155
|
NodeBS result;
|
|
156
|
-
result.set(
|
|
156
|
+
result.set(getConstantFieldIdx());
|
|
157
157
|
return result;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
LocationSet LocationSet::operator+ (const LocationSet& rhs) const
|
|
161
161
|
{
|
|
162
162
|
LocationSet ls(rhs);
|
|
163
|
-
ls.fldIdx +=
|
|
163
|
+
ls.fldIdx += getConstantFieldIdx();
|
|
164
164
|
OffsetVarAndGepTypePairs::const_iterator it = getOffsetVarAndGepTypePairVec().begin();
|
|
165
165
|
OffsetVarAndGepTypePairs::const_iterator eit = getOffsetVarAndGepTypePairVec().end();
|
|
166
166
|
for (; it != eit; ++it)
|
|
@@ -221,7 +221,7 @@ std::string LocationSet::dump() const
|
|
|
221
221
|
std::string str;
|
|
222
222
|
std::stringstream rawstr(str);
|
|
223
223
|
|
|
224
|
-
rawstr << "LocationSet\tField_Index: " <<
|
|
224
|
+
rawstr << "LocationSet\tField_Index: " << getConstantFieldIdx();
|
|
225
225
|
rawstr << ",\tNum-Stride: {";
|
|
226
226
|
const OffsetVarAndGepTypePairs& vec = getOffsetVarAndGepTypePairVec();
|
|
227
227
|
OffsetVarAndGepTypePairs::const_iterator it = vec.begin();
|
|
@@ -261,27 +261,23 @@ void SaberSVFGBuilder::rmIncomingEdgeForSUStore(BVDataPTAImpl* pta)
|
|
|
261
261
|
|
|
262
262
|
if(const StoreSVFGNode* stmtNode = SVFUtil::dyn_cast<StoreSVFGNode>(node))
|
|
263
263
|
{
|
|
264
|
-
|
|
264
|
+
if(SVFUtil::isa<StoreStmt>(stmtNode->getPAGEdge()))
|
|
265
265
|
{
|
|
266
|
-
|
|
266
|
+
NodeID singleton;
|
|
267
|
+
if(isStrongUpdate(node, singleton, pta))
|
|
267
268
|
{
|
|
268
|
-
|
|
269
|
-
|
|
269
|
+
Set<SVFGEdge*> toRemove;
|
|
270
|
+
for (SVFGNode::const_iterator it2 = node->InEdgeBegin(), eit2 = node->InEdgeEnd(); it2 != eit2; ++it2)
|
|
270
271
|
{
|
|
271
|
-
|
|
272
|
-
for (SVFGNode::const_iterator it2 = node->InEdgeBegin(), eit2 = node->InEdgeEnd(); it2 != eit2; ++it2)
|
|
272
|
+
if ((*it2)->isIndirectVFGEdge())
|
|
273
273
|
{
|
|
274
|
-
|
|
275
|
-
{
|
|
276
|
-
toRemove.insert(*it2);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
for (SVFGEdge* edge: toRemove)
|
|
280
|
-
{
|
|
281
|
-
svfg->removeSVFGEdge(edge);
|
|
274
|
+
toRemove.insert(*it2);
|
|
282
275
|
}
|
|
283
276
|
}
|
|
284
|
-
|
|
277
|
+
for (SVFGEdge* edge: toRemove)
|
|
278
|
+
{
|
|
279
|
+
svfg->removeSVFGEdge(edge);
|
|
280
|
+
}
|
|
285
281
|
}
|
|
286
282
|
}
|
|
287
283
|
}
|
package/svf/lib/SVFIR/SVFIR.cpp
CHANGED
|
@@ -430,7 +430,7 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const LocationSet& ls)
|
|
|
430
430
|
LocationSet newLS = pag->getSymbolInfo()->getModulusOffset(obj,ls);
|
|
431
431
|
|
|
432
432
|
// Base and first field are the same memory location.
|
|
433
|
-
if (Options::FirstFieldEqBase() && newLS.
|
|
433
|
+
if (Options::FirstFieldEqBase() && newLS.getConstantFieldIdx() == 0) return base;
|
|
434
434
|
|
|
435
435
|
NodeLocationSetMap::iterator iter = GepObjVarMap.find(std::make_pair(base, newLS));
|
|
436
436
|
if (iter == GepObjVarMap.end())
|
|
@@ -450,7 +450,7 @@ NodeID SVFIR::addGepObjNode(const MemObj* obj, const LocationSet& ls)
|
|
|
450
450
|
assert(0==GepObjVarMap.count(std::make_pair(base, ls))
|
|
451
451
|
&& "this node should not be created before");
|
|
452
452
|
|
|
453
|
-
NodeID gepId = NodeIDAllocator::get()->allocateGepObjectId(base, ls.
|
|
453
|
+
NodeID gepId = NodeIDAllocator::get()->allocateGepObjectId(base, ls.getConstantFieldIdx(), Options::MaxFieldLimit());
|
|
454
454
|
GepObjVarMap[std::make_pair(base, ls)] = gepId;
|
|
455
455
|
GepObjVar *node = new GepObjVar(obj, gepId, ls);
|
|
456
456
|
memToFieldsMap[base].set(gepId);
|
|
@@ -145,7 +145,7 @@ const std::string GepObjVar::toString() const
|
|
|
145
145
|
{
|
|
146
146
|
std::string str;
|
|
147
147
|
std::stringstream rawstr(str);
|
|
148
|
-
rawstr << "GepObjVar ID: " << getId() << " with offset_" + std::to_string(ls.
|
|
148
|
+
rawstr << "GepObjVar ID: " << getId() << " with offset_" + std::to_string(ls.getConstantFieldIdx());
|
|
149
149
|
if (Options::ShowSVFIRValue())
|
|
150
150
|
{
|
|
151
151
|
rawstr << "\n";
|
|
@@ -98,7 +98,7 @@ LocationSet SymbolTableInfo::getModulusOffset(const MemObj* obj, const LocationS
|
|
|
98
98
|
/// of current struct. Make the offset positive so we can still get a node within current
|
|
99
99
|
/// struct to represent this obj.
|
|
100
100
|
|
|
101
|
-
s32_t offset = ls.
|
|
101
|
+
s32_t offset = ls.getConstantFieldIdx();
|
|
102
102
|
if(offset < 0)
|
|
103
103
|
{
|
|
104
104
|
writeWrnMsg("try to create a gep node with negative offset.");
|
|
@@ -392,13 +392,13 @@ bool ObjTypeInfo::isNonPtrFieldObj(const LocationSet& ls)
|
|
|
392
392
|
else
|
|
393
393
|
sz = SymbolTableInfo::SymbolInfo()->getTypeInfo(ety)->getFlattenFieldTypes().size();
|
|
394
394
|
|
|
395
|
-
if(sz <= (u32_t)ls.
|
|
395
|
+
if(sz <= (u32_t) ls.getConstantFieldIdx())
|
|
396
396
|
{
|
|
397
397
|
writeWrnMsg("out of bound error when accessing the struct/array");
|
|
398
398
|
return false;
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
-
const SVFType* elemTy = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(ety, ls.
|
|
401
|
+
const SVFType* elemTy = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(ety, ls.getConstantFieldIdx());
|
|
402
402
|
return (elemTy->isPointerTy() == false);
|
|
403
403
|
}
|
|
404
404
|
else
|
|
@@ -272,6 +272,8 @@ bool SVFIRBuilder::computeGepOffset(const User *V, LocationSet& ls)
|
|
|
272
272
|
//s32_t bo = byteOffset.getSExtValue();
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
bool isConst = true;
|
|
276
|
+
|
|
275
277
|
for (bridge_gep_iterator gi = bridge_gep_begin(*V), ge = bridge_gep_end(*V);
|
|
276
278
|
gi != ge; ++gi)
|
|
277
279
|
{
|
|
@@ -293,7 +295,7 @@ bool SVFIRBuilder::computeGepOffset(const User *V, LocationSet& ls)
|
|
|
293
295
|
continue;
|
|
294
296
|
s32_t idx = op->getSExtValue();
|
|
295
297
|
u32_t offset = pag->getSymbolInfo()->getFlattenedElemIdx(LLVMModuleSet::getLLVMModuleSet()->getSVFType(arrTy), idx);
|
|
296
|
-
ls.setFldIdx(ls.
|
|
298
|
+
ls.setFldIdx(ls.getConstantFieldIdx() + offset);
|
|
297
299
|
}
|
|
298
300
|
else if (const StructType *ST = SVFUtil::dyn_cast<StructType>(gepTy))
|
|
299
301
|
{
|
|
@@ -301,7 +303,7 @@ bool SVFIRBuilder::computeGepOffset(const User *V, LocationSet& ls)
|
|
|
301
303
|
//The actual index
|
|
302
304
|
s32_t idx = op->getSExtValue();
|
|
303
305
|
u32_t offset = pag->getSymbolInfo()->getFlattenedElemIdx(LLVMModuleSet::getLLVMModuleSet()->getSVFType(ST), idx);
|
|
304
|
-
ls.setFldIdx(ls.
|
|
306
|
+
ls.setFldIdx(ls.getConstantFieldIdx() + offset);
|
|
305
307
|
}
|
|
306
308
|
else if (gepTy->isSingleValueType())
|
|
307
309
|
{
|
|
@@ -309,17 +311,17 @@ bool SVFIRBuilder::computeGepOffset(const User *V, LocationSet& ls)
|
|
|
309
311
|
// If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index)
|
|
310
312
|
// If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index)
|
|
311
313
|
if(!op && gepTy->isPointerTy() && getPtrElementType(SVFUtil::dyn_cast<PointerType>(gepTy))->isSingleValueType())
|
|
312
|
-
|
|
314
|
+
isConst = false;
|
|
313
315
|
|
|
314
316
|
// The actual index
|
|
315
317
|
//s32_t idx = op->getSExtValue();
|
|
316
318
|
|
|
317
319
|
// For pointer arithmetic we ignore the byte offset
|
|
318
320
|
// consider using inferFieldIdxFromByteOffset(geopOp,dataLayout,ls,idx)?
|
|
319
|
-
// ls.setFldIdx(ls.
|
|
321
|
+
// ls.setFldIdx(ls.getConstantFieldIdx() + inferFieldIdxFromByteOffset(geopOp,idx));
|
|
320
322
|
}
|
|
321
323
|
}
|
|
322
|
-
return
|
|
324
|
+
return isConst;
|
|
323
325
|
}
|
|
324
326
|
|
|
325
327
|
/*!
|
|
@@ -1178,8 +1180,10 @@ void SVFIRBuilder::addComplexConsForExt(const Value* D, const Value* S, const Va
|
|
|
1178
1180
|
for (u32_t index = 0; index < sz; index++)
|
|
1179
1181
|
{
|
|
1180
1182
|
LLVMModuleSet* llvmmodule = LLVMModuleSet::getLLVMModuleSet();
|
|
1181
|
-
const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->getSVFType(dtype),
|
|
1182
|
-
|
|
1183
|
+
const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->getSVFType(dtype),
|
|
1184
|
+
fields[index].getConstantFieldIdx());
|
|
1185
|
+
const SVFType* sElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->getSVFType(stype),
|
|
1186
|
+
fields[index].getConstantFieldIdx());
|
|
1183
1187
|
NodeID dField = getGepValVar(D,fields[index],dElementType);
|
|
1184
1188
|
NodeID sField = getGepValVar(S,fields[index],sElementType);
|
|
1185
1189
|
NodeID dummy = pag->addDummyValNode();
|
|
@@ -1387,7 +1391,8 @@ void SVFIRBuilder::handleExtCall(CallBase* cs, const Function *callee)
|
|
|
1387
1391
|
//For each field (i), add store edge *(arg0 + i) = arg1
|
|
1388
1392
|
for (u32_t index = 0; index < sz; index++)
|
|
1389
1393
|
{
|
|
1390
|
-
const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(LLVMModuleSet::getLLVMModuleSet()->getSVFType(dtype),
|
|
1394
|
+
const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(LLVMModuleSet::getLLVMModuleSet()->getSVFType(dtype),
|
|
1395
|
+
dstFields[index].getConstantFieldIdx());
|
|
1391
1396
|
NodeID dField = getGepValVar(cs->getArgOperand(op.getOperands()[0]), dstFields[index], dElementType);
|
|
1392
1397
|
addStoreEdge(getValueNode(cs->getArgOperand(op.getOperands()[1])),dField);
|
|
1393
1398
|
}
|
|
@@ -1430,7 +1435,7 @@ void SVFIRBuilder::handleExtCall(CallBase* cs, const Function *callee)
|
|
|
1430
1435
|
// We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
|
|
1431
1436
|
// Now we calculate the offset from base to vArg3
|
|
1432
1437
|
NodeID vnArg3 = pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(vArg3));
|
|
1433
|
-
s32_t offset = getLocationSetFromBaseNode(vnArg3).
|
|
1438
|
+
s32_t offset = getLocationSetFromBaseNode(vnArg3).getConstantFieldIdx();
|
|
1434
1439
|
|
|
1435
1440
|
// We get all flattened fields of base
|
|
1436
1441
|
vector<LocationSet> fields;
|
|
@@ -1442,7 +1447,8 @@ void SVFIRBuilder::handleExtCall(CallBase* cs, const Function *callee)
|
|
|
1442
1447
|
{
|
|
1443
1448
|
if((u32_t)i >= fields.size())
|
|
1444
1449
|
break;
|
|
1445
|
-
const SVFType* elementType = pag->getSymbolInfo()->getFlatternedElemType(LLVMModuleSet::getLLVMModuleSet()->getSVFType(type),
|
|
1450
|
+
const SVFType* elementType = pag->getSymbolInfo()->getFlatternedElemType(LLVMModuleSet::getLLVMModuleSet()->getSVFType(type),
|
|
1451
|
+
fields[i].getConstantFieldIdx());
|
|
1446
1452
|
NodeID vnD = getGepValVar(vArg3, fields[i], elementType);
|
|
1447
1453
|
NodeID vnS = getValueNode(vArg1);
|
|
1448
1454
|
if(vnD && vnS)
|