svf-tools 1.0.993 → 1.0.995
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/package.json +1 -1
- package/svf/include/Graphs/CDG.h +18 -1
- package/svf/include/Graphs/CFLGraph.h +19 -1
- package/svf/include/Graphs/CHG.h +19 -1
- package/svf/include/Graphs/CallGraph.h +19 -1
- package/svf/include/Graphs/ConsGNode.h +19 -1
- package/svf/include/Graphs/GenericGraph.h +243 -17
- package/svf/include/Graphs/ICFG.h +0 -96
- package/svf/include/Graphs/ICFGNode.h +55 -22
- package/svf/include/Graphs/SVFG.h +2 -2
- package/svf/include/Graphs/SVFGNode.h +5 -17
- package/svf/include/Graphs/SVFGOPT.h +2 -1
- package/svf/include/Graphs/ThreadCallGraph.h +5 -4
- package/svf/include/Graphs/VFG.h +2 -2
- package/svf/include/Graphs/VFGNode.h +99 -26
- package/svf/include/MTA/TCT.h +19 -1
- package/svf/include/MemoryModel/PointerAnalysis.h +1 -1
- package/svf/include/MemoryModel/PointerAnalysisImpl.h +4 -0
- package/svf/include/SABER/SaberCondAllocator.h +2 -2
- package/svf/include/SVFIR/SVFFileSystem.h +1 -1
- package/svf/include/SVFIR/SVFIR.h +2 -2
- package/svf/include/SVFIR/SVFVariables.h +68 -38
- package/svf/include/SVFIR/SymbolTableInfo.h +11 -1
- package/svf/include/Util/SVFUtil.h +1 -1
- package/svf/include/Util/ThreadAPI.h +8 -2
- package/svf/include/WPA/Andersen.h +26 -13
- package/svf/include/WPA/Steensgaard.h +10 -20
- package/svf/include/WPA/TypeAnalysis.h +10 -3
- package/svf/lib/AE/Svfexe/AEDetector.cpp +4 -2
- package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +10 -12
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +2 -0
- package/svf/lib/DDA/ContextDDA.cpp +12 -8
- package/svf/lib/Graphs/ICFG.cpp +9 -93
- package/svf/lib/Graphs/SVFG.cpp +1 -1
- package/svf/lib/Graphs/ThreadCallGraph.cpp +10 -2
- package/svf/lib/Graphs/VFG.cpp +2 -4
- package/svf/lib/MSSA/MemRegion.cpp +2 -2
- package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +37 -0
- package/svf/lib/SABER/LeakChecker.cpp +1 -2
- package/svf/lib/SABER/SaberCondAllocator.cpp +13 -16
- package/svf/lib/SABER/SaberSVFGBuilder.cpp +2 -2
- package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -6
- package/svf/lib/SVFIR/SVFVariables.cpp +3 -0
- package/svf/lib/SVFIR/SymbolTableInfo.cpp +3 -2
- package/svf/lib/Util/ThreadAPI.cpp +15 -5
- package/svf/lib/WPA/Andersen.cpp +205 -151
- package/svf/lib/WPA/Steensgaard.cpp +1 -163
- package/svf-llvm/include/SVF-LLVM/DCHG.h +1 -1
- package/svf-llvm/include/SVF-LLVM/ICFGBuilder.h +93 -23
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +84 -0
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +15 -0
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +19 -12
- package/svf-llvm/lib/ICFGBuilder.cpp +125 -54
- package/svf-llvm/lib/LLVMLoopAnalysis.cpp +6 -11
- package/svf-llvm/lib/LLVMModule.cpp +54 -0
- package/svf-llvm/lib/LLVMUtil.cpp +15 -0
- package/svf-llvm/lib/SVFIRBuilder.cpp +92 -76
- package/svf-llvm/lib/SVFIRExtAPI.cpp +5 -5
- package/svf-llvm/lib/SymbolTableBuilder.cpp +4 -4
package/svf/lib/Graphs/ICFG.cpp
CHANGED
|
@@ -229,102 +229,20 @@ ICFG::~ICFG()
|
|
|
229
229
|
icfgNodeToSVFLoopVec.clear();
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
/// Get a basic block ICFGNode
|
|
233
|
-
ICFGNode* ICFG::getICFGNode(const SVFInstruction* inst)
|
|
234
|
-
{
|
|
235
|
-
ICFGNode* node;
|
|
236
|
-
if(SVFUtil::isNonInstricCallSite(inst))
|
|
237
|
-
node = getCallICFGNode(inst);
|
|
238
|
-
else if(SVFUtil::isIntrinsicInst(inst))
|
|
239
|
-
node = getIntraICFGNode(inst);
|
|
240
|
-
else
|
|
241
|
-
node = getIntraICFGNode(inst);
|
|
242
|
-
|
|
243
|
-
assert (node!=nullptr && "no ICFGNode for this instruction?");
|
|
244
|
-
return node;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
bool ICFG::hasICFGNode(const SVF::SVFInstruction* inst)
|
|
248
|
-
{
|
|
249
|
-
ICFGNode* node;
|
|
250
|
-
if(SVFUtil::isNonInstricCallSite(inst))
|
|
251
|
-
node = getCallBlock(inst);
|
|
252
|
-
else if(SVFUtil::isIntrinsicInst(inst))
|
|
253
|
-
node = getIntraBlock(inst);
|
|
254
|
-
else
|
|
255
|
-
node = getIntraBlock(inst);
|
|
256
|
-
|
|
257
|
-
return node != nullptr;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
CallICFGNode* ICFG::getCallICFGNode(const SVFInstruction* inst)
|
|
262
|
-
{
|
|
263
|
-
assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
|
|
264
|
-
assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
265
|
-
CallICFGNode* node = getCallBlock(inst);
|
|
266
|
-
assert (node!=nullptr && "no CallICFGNode for this instruction?");
|
|
267
|
-
return node;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
CallICFGNode* ICFG::addCallICFGNode(const SVFInstruction* inst)
|
|
271
|
-
{
|
|
272
|
-
assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
|
|
273
|
-
assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
274
|
-
assert(getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
|
|
275
|
-
return addCallBlock(inst);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
RetICFGNode* ICFG::getRetICFGNode(const SVFInstruction* inst)
|
|
279
|
-
{
|
|
280
|
-
assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
|
|
281
|
-
assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
282
|
-
RetICFGNode* node = getRetBlock(inst);
|
|
283
|
-
assert (node!=nullptr && "no RetICFGNode for this instruction?");
|
|
284
|
-
return node;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
RetICFGNode* ICFG::addRetICFGNode(const SVFInstruction* inst)
|
|
288
|
-
{
|
|
289
|
-
assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
|
|
290
|
-
assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
291
|
-
assert(getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
|
|
292
|
-
return addRetBlock(inst);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
IntraICFGNode* ICFG::getIntraICFGNode(const SVFInstruction* inst)
|
|
296
|
-
{
|
|
297
|
-
IntraICFGNode* node = getIntraBlock(inst);
|
|
298
|
-
assert (node!=nullptr && "no IntraICFGNode for this instruction?");
|
|
299
|
-
return node;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
IntraICFGNode* ICFG::addIntraICFGNode(const SVFInstruction* inst)
|
|
304
|
-
{
|
|
305
|
-
IntraICFGNode* node = getIntraBlock(inst);
|
|
306
|
-
assert (node==nullptr && "no IntraICFGNode for this instruction?");
|
|
307
|
-
return addIntraBlock(inst);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
232
|
|
|
311
233
|
/// Add a function entry node
|
|
312
234
|
FunEntryICFGNode* ICFG::getFunEntryICFGNode(const SVFFunction* fun)
|
|
313
235
|
{
|
|
314
|
-
FunEntryICFGNode*
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
else
|
|
318
|
-
return b;
|
|
236
|
+
FunEntryICFGNode* entry = getFunEntryBlock(fun);
|
|
237
|
+
assert (entry && "fun entry not created in ICFGBuilder?");
|
|
238
|
+
return entry;
|
|
319
239
|
}
|
|
320
240
|
/// Add a function exit node
|
|
321
241
|
FunExitICFGNode* ICFG::getFunExitICFGNode(const SVFFunction* fun)
|
|
322
242
|
{
|
|
323
|
-
FunExitICFGNode*
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
else
|
|
327
|
-
return b;
|
|
243
|
+
FunExitICFGNode* exit = getFunExitBlock(fun);
|
|
244
|
+
assert (exit && "fun exit not created in ICFGBuilder?");
|
|
245
|
+
return exit;
|
|
328
246
|
}
|
|
329
247
|
|
|
330
248
|
/*!
|
|
@@ -504,15 +422,13 @@ void ICFG::updateCallGraph(CallGraph* callgraph)
|
|
|
504
422
|
CallGraph::CallEdgeMap::const_iterator eiter = callgraph->getIndCallMap().end();
|
|
505
423
|
for (; iter != eiter; iter++)
|
|
506
424
|
{
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
assert(callBlock->isIndirectCall() && "this is not an indirect call?");
|
|
425
|
+
CallICFGNode* callBlockNode = const_cast<CallICFGNode*>(iter->first);
|
|
426
|
+
assert(callBlockNode->isIndirectCall() && "this is not an indirect call?");
|
|
510
427
|
const CallGraph::FunctionSet & functions = iter->second;
|
|
511
428
|
for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
|
|
512
429
|
{
|
|
513
430
|
const SVFFunction* callee = *func_iter;
|
|
514
|
-
|
|
515
|
-
RetICFGNode* retBlockNode = getRetICFGNode(cs);
|
|
431
|
+
RetICFGNode* retBlockNode = const_cast<RetICFGNode*>(callBlockNode->getRetICFGNode());
|
|
516
432
|
/// if this is an external function (no function body), connect calleeEntryNode to calleeExitNode
|
|
517
433
|
if (isExtCall(callee))
|
|
518
434
|
addIntraEdge(callBlockNode, retBlockNode);
|
package/svf/lib/Graphs/SVFG.cpp
CHANGED
|
@@ -586,7 +586,7 @@ void SVFG::dump(const std::string& file, bool simple)
|
|
|
586
586
|
void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, const SVFFunction* callee, SVFGEdgeSetTy& edges)
|
|
587
587
|
{
|
|
588
588
|
CallSiteID csId = getCallSiteID(callICFGNode, callee);
|
|
589
|
-
RetICFGNode* retICFGNode =
|
|
589
|
+
const RetICFGNode* retICFGNode = callICFGNode->getRetICFGNode();
|
|
590
590
|
|
|
591
591
|
// Find inter direct call edges between actual param and formal param.
|
|
592
592
|
if (pag->hasCallSiteArgsMap(callICFGNode) && pag->hasFunArgsList(callee))
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
#include "SVFIR/SVFModule.h"
|
|
31
31
|
#include "Graphs/ThreadCallGraph.h"
|
|
32
32
|
#include "Util/ThreadAPI.h"
|
|
33
|
+
#include "SVFIR/SVFIR.h"
|
|
34
|
+
#include "MemoryModel/PointerAnalysisImpl.h"
|
|
33
35
|
|
|
34
36
|
using namespace SVF;
|
|
35
37
|
using namespace SVFUtil;
|
|
@@ -119,7 +121,7 @@ void ThreadCallGraph::updateJoinEdge(PointerAnalysis* pta)
|
|
|
119
121
|
/*!
|
|
120
122
|
* Add direct fork edges
|
|
121
123
|
*/
|
|
122
|
-
|
|
124
|
+
bool ThreadCallGraph::addDirectForkEdge(const CallICFGNode* cs)
|
|
123
125
|
{
|
|
124
126
|
|
|
125
127
|
CallGraphNode* caller = getCallGraphNode(cs->getCaller());
|
|
@@ -137,13 +139,16 @@ void ThreadCallGraph::addDirectForkEdge(const CallICFGNode* cs)
|
|
|
137
139
|
|
|
138
140
|
addEdge(edge);
|
|
139
141
|
addThreadForkEdgeSetMap(cs, edge);
|
|
142
|
+
return true;
|
|
140
143
|
}
|
|
144
|
+
else
|
|
145
|
+
return false;
|
|
141
146
|
}
|
|
142
147
|
|
|
143
148
|
/*!
|
|
144
149
|
* Add indirect fork edge to update call graph
|
|
145
150
|
*/
|
|
146
|
-
|
|
151
|
+
bool ThreadCallGraph::addIndirectForkEdge(const CallICFGNode* cs, const SVFFunction* calleefun)
|
|
147
152
|
{
|
|
148
153
|
CallGraphNode* caller = getCallGraphNode(cs->getCaller());
|
|
149
154
|
CallGraphNode* callee = getCallGraphNode(calleefun);
|
|
@@ -159,7 +164,10 @@ void ThreadCallGraph::addIndirectForkEdge(const CallICFGNode* cs, const SVFFunct
|
|
|
159
164
|
|
|
160
165
|
addEdge(edge);
|
|
161
166
|
addThreadForkEdgeSetMap(cs, edge);
|
|
167
|
+
return true;
|
|
162
168
|
}
|
|
169
|
+
else
|
|
170
|
+
return false;
|
|
163
171
|
}
|
|
164
172
|
|
|
165
173
|
/*!
|
package/svf/lib/Graphs/VFG.cpp
CHANGED
|
@@ -835,8 +835,7 @@ void VFG::connectDirectVFGEdges()
|
|
|
835
835
|
for(RetPESet::const_iterator it = calleeRet->retPEBegin(), eit = calleeRet->retPEEnd(); it!=eit; ++it)
|
|
836
836
|
{
|
|
837
837
|
ActualRetVFGNode* callsiteRev = getActualRetVFGNode((*it)->getLHSVar());
|
|
838
|
-
const CallICFGNode*
|
|
839
|
-
CallICFGNode* callBlockNode = pag->getICFG()->getCallICFGNode(retBlockNode->getCallSite());
|
|
838
|
+
const CallICFGNode* callBlockNode = (*it)->getCallSite();
|
|
840
839
|
addInterEdgeFromFRToAR(calleeRet,callsiteRev, getCallSiteID(callBlockNode, calleeRet->getFun()));
|
|
841
840
|
}
|
|
842
841
|
}
|
|
@@ -974,9 +973,8 @@ void VFG::updateCallGraph(PointerAnalysis* pta)
|
|
|
974
973
|
void VFG::connectCallerAndCallee(const CallICFGNode* callBlockNode, const SVFFunction* callee, VFGEdgeSetTy& edges)
|
|
975
974
|
{
|
|
976
975
|
SVFIR * pag = SVFIR::getPAG();
|
|
977
|
-
ICFG * icfg = pag->getICFG();
|
|
978
976
|
CallSiteID csId = getCallSiteID(callBlockNode, callee);
|
|
979
|
-
RetICFGNode* retBlockNode =
|
|
977
|
+
const RetICFGNode* retBlockNode = callBlockNode->getRetICFGNode();
|
|
980
978
|
// connect actual and formal param
|
|
981
979
|
if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(callee) &&
|
|
982
980
|
matchArgs(callBlockNode, callee))
|
|
@@ -479,8 +479,8 @@ void MRGenerator::collectCallSitePts(const CallICFGNode* cs)
|
|
|
479
479
|
/// collect the pts chain of the callsite arguments
|
|
480
480
|
NodeBS& argsPts = csToCallSiteArgsPtsMap[cs];
|
|
481
481
|
SVFIR* pag = pta->getPAG();
|
|
482
|
-
CallICFGNode* callBlockNode =
|
|
483
|
-
RetICFGNode* retBlockNode =
|
|
482
|
+
CallICFGNode* callBlockNode = const_cast<CallICFGNode*>(cs);
|
|
483
|
+
const RetICFGNode* retBlockNode = cs->getRetICFGNode();
|
|
484
484
|
|
|
485
485
|
WorkList worklist;
|
|
486
486
|
if (pag->hasCallSiteArgsMap(callBlockNode))
|
|
@@ -507,6 +507,43 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites,
|
|
|
507
507
|
}
|
|
508
508
|
}
|
|
509
509
|
|
|
510
|
+
/*!
|
|
511
|
+
* On the fly call graph construction respecting forksite
|
|
512
|
+
* callsites is candidate indirect callsites need to be analyzed based on points-to results
|
|
513
|
+
* newEdges is the new indirect call edges discovered
|
|
514
|
+
*/
|
|
515
|
+
void BVDataPTAImpl::onTheFlyThreadCallGraphSolve(const CallSiteToFunPtrMap& callsites,
|
|
516
|
+
CallEdgeMap& newForkEdges)
|
|
517
|
+
{
|
|
518
|
+
// add indirect fork edges
|
|
519
|
+
if(ThreadCallGraph *tdCallGraph = SVFUtil::dyn_cast<ThreadCallGraph>(callgraph))
|
|
520
|
+
{
|
|
521
|
+
for(CallSiteSet::const_iterator it = tdCallGraph->forksitesBegin(),
|
|
522
|
+
eit = tdCallGraph->forksitesEnd(); it != eit; ++it)
|
|
523
|
+
{
|
|
524
|
+
const SVFValue* forkedVal =tdCallGraph->getThreadAPI()->getForkedFun(*it);
|
|
525
|
+
if(SVFUtil::dyn_cast<SVFFunction>(forkedVal) == nullptr)
|
|
526
|
+
{
|
|
527
|
+
SVFIR *pag = this->getPAG();
|
|
528
|
+
const NodeBS targets = this->getPts(pag->getValueNode(forkedVal)).toNodeBS();
|
|
529
|
+
for(NodeBS::iterator ii = targets.begin(), ie = targets.end(); ii != ie; ++ii)
|
|
530
|
+
{
|
|
531
|
+
if(ObjVar *objPN = SVFUtil::dyn_cast<ObjVar>(pag->getGNode(*ii)))
|
|
532
|
+
{
|
|
533
|
+
const MemObj *obj = pag->getObject(objPN);
|
|
534
|
+
if(obj->isFunction())
|
|
535
|
+
{
|
|
536
|
+
const SVFFunction *svfForkedFun = SVFUtil::cast<SVFFunction>(obj->getValue());
|
|
537
|
+
if(tdCallGraph->addIndirectForkEdge(*it, svfForkedFun))
|
|
538
|
+
newForkEdges[*it].insert(svfForkedFun);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
510
547
|
/*!
|
|
511
548
|
* Normalize points-to information for field-sensitive analysis
|
|
512
549
|
*/
|
|
@@ -41,7 +41,6 @@ void LeakChecker::initSrcs()
|
|
|
41
41
|
{
|
|
42
42
|
|
|
43
43
|
SVFIR* pag = getPAG();
|
|
44
|
-
ICFG* icfg = pag->getICFG();
|
|
45
44
|
for(SVFIR::CSToRetMap::iterator it = pag->getCallSiteRets().begin(),
|
|
46
45
|
eit = pag->getCallSiteRets().end(); it!=eit; ++it)
|
|
47
46
|
{
|
|
@@ -65,7 +64,7 @@ void LeakChecker::initSrcs()
|
|
|
65
64
|
while (!worklist.empty())
|
|
66
65
|
{
|
|
67
66
|
const CallICFGNode* cs = worklist.pop();
|
|
68
|
-
const RetICFGNode* retBlockNode =
|
|
67
|
+
const RetICFGNode* retBlockNode = cs->getRetICFGNode();
|
|
69
68
|
const PAGNode* pagNode = pag->getCallSiteRet(retBlockNode);
|
|
70
69
|
const SVFGNode* node = getSVFG()->getDefSVFGNode(pagNode);
|
|
71
70
|
if (visited.test(node->getId()) == 0)
|
|
@@ -186,7 +186,8 @@ SaberCondAllocator::evaluateTestNullLikeExpr(const BranchStmt *branchStmt, const
|
|
|
186
186
|
|
|
187
187
|
const SVFBasicBlock* succ1 = branchStmt->getSuccessor(0)->getBB();
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
const ValVar* condVar = SVFUtil::cast<ValVar>(branchStmt->getCondition());
|
|
190
|
+
if (isTestNullExpr(SVFUtil::cast<ICFGNode>(condVar->getGNode())))
|
|
190
191
|
{
|
|
191
192
|
// succ is then branch
|
|
192
193
|
if (succ1 == succ)
|
|
@@ -195,7 +196,7 @@ SaberCondAllocator::evaluateTestNullLikeExpr(const BranchStmt *branchStmt, const
|
|
|
195
196
|
else
|
|
196
197
|
return getTrueCond();
|
|
197
198
|
}
|
|
198
|
-
if (isTestNotNullExpr(
|
|
199
|
+
if (isTestNotNullExpr(SVFUtil::cast<ICFGNode>(condVar->getGNode())))
|
|
199
200
|
{
|
|
200
201
|
// succ is then branch
|
|
201
202
|
if (succ1 == succ)
|
|
@@ -341,31 +342,27 @@ bool SaberCondAllocator::isNECmp(const CmpStmt *cmp) const
|
|
|
341
342
|
return (cmp->getPredicate() == CmpStmt::ICMP_NE);
|
|
342
343
|
}
|
|
343
344
|
|
|
344
|
-
bool SaberCondAllocator::isTestNullExpr(const
|
|
345
|
+
bool SaberCondAllocator::isTestNullExpr(const ICFGNode* test) const
|
|
345
346
|
{
|
|
346
|
-
if(
|
|
347
|
+
if(!test) return false;
|
|
348
|
+
for(const SVFStmt* stmt : PAG::getPAG()->getSVFStmtList(test))
|
|
347
349
|
{
|
|
348
|
-
|
|
350
|
+
if(const CmpStmt* cmp = SVFUtil::dyn_cast<CmpStmt>(stmt))
|
|
349
351
|
{
|
|
350
|
-
|
|
351
|
-
{
|
|
352
|
-
return isTestContainsNullAndTheValue(cmp) && isEQCmp(cmp);
|
|
353
|
-
}
|
|
352
|
+
return isTestContainsNullAndTheValue(cmp) && isEQCmp(cmp);
|
|
354
353
|
}
|
|
355
354
|
}
|
|
356
355
|
return false;
|
|
357
356
|
}
|
|
358
357
|
|
|
359
|
-
bool SaberCondAllocator::isTestNotNullExpr(const
|
|
358
|
+
bool SaberCondAllocator::isTestNotNullExpr(const ICFGNode* test) const
|
|
360
359
|
{
|
|
361
|
-
if(
|
|
360
|
+
if(!test) return false;
|
|
361
|
+
for(const SVFStmt* stmt : PAG::getPAG()->getSVFStmtList(test))
|
|
362
362
|
{
|
|
363
|
-
|
|
363
|
+
if(const CmpStmt* cmp = SVFUtil::dyn_cast<CmpStmt>(stmt))
|
|
364
364
|
{
|
|
365
|
-
|
|
366
|
-
{
|
|
367
|
-
return isTestContainsNullAndTheValue(cmp) && isNECmp(cmp);
|
|
368
|
-
}
|
|
365
|
+
return isTestContainsNullAndTheValue(cmp) && isNECmp(cmp);
|
|
369
366
|
}
|
|
370
367
|
}
|
|
371
368
|
return false;
|
|
@@ -137,8 +137,8 @@ PointsTo& SaberSVFGBuilder::CollectPtsChain(BVDataPTAImpl* pta, NodeID id, NodeT
|
|
|
137
137
|
{
|
|
138
138
|
if(pta->isFIObjNode(baseId) && pag->getGNode(baseId)->hasValue())
|
|
139
139
|
{
|
|
140
|
-
|
|
141
|
-
if(
|
|
140
|
+
ValVar* valVar = SVFUtil::dyn_cast<ValVar>(pag->getGNode(baseId));
|
|
141
|
+
if(valVar && valVar->getGNode() && SVFUtil::isExtCall(SVFUtil::cast<ICFGNode>(valVar->getGNode())))
|
|
142
142
|
{
|
|
143
143
|
return pts;
|
|
144
144
|
}
|
|
@@ -1115,9 +1115,6 @@ cJSON* SVFIRWriter::toJson(const ICFG* icfg)
|
|
|
1115
1115
|
F(totalICFGNode);
|
|
1116
1116
|
F(FunToFunEntryNodeMap);
|
|
1117
1117
|
F(FunToFunExitNodeMap);
|
|
1118
|
-
F(CSToCallNodeMap);
|
|
1119
|
-
F(CSToRetNodeMap);
|
|
1120
|
-
F(InstToBlockNodeMap);
|
|
1121
1118
|
F(globalBlockNode);
|
|
1122
1119
|
F(icfgNodeToSVFLoopVec);
|
|
1123
1120
|
#undef F
|
|
@@ -1741,9 +1738,6 @@ void SVFIRReader::readJson(ICFG* icfg)
|
|
|
1741
1738
|
F(totalICFGNode);
|
|
1742
1739
|
F(FunToFunEntryNodeMap);
|
|
1743
1740
|
F(FunToFunExitNodeMap);
|
|
1744
|
-
F(CSToCallNodeMap);
|
|
1745
|
-
F(CSToRetNodeMap);
|
|
1746
|
-
F(InstToBlockNodeMap);
|
|
1747
1741
|
F(globalBlockNode);
|
|
1748
1742
|
F(icfgNodeToSVFLoopVec);
|
|
1749
1743
|
#undef F
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
#include "Util/Options.h"
|
|
35
35
|
#include "SVFIR/SVFModule.h"
|
|
36
36
|
|
|
37
|
+
|
|
37
38
|
using namespace std;
|
|
38
39
|
using namespace SVF;
|
|
39
40
|
using namespace SVFUtil;
|
|
@@ -373,8 +374,8 @@ void MemObj::setFieldSensitive()
|
|
|
373
374
|
/*!
|
|
374
375
|
* Constructor of a memory object
|
|
375
376
|
*/
|
|
376
|
-
MemObj::MemObj(SymID id, ObjTypeInfo* ti, const SVFValue* val) :
|
|
377
|
-
typeInfo(ti), refVal(val), symId(id)
|
|
377
|
+
MemObj::MemObj(SymID id, ObjTypeInfo* ti, const SVFValue* val, const SVFBaseNode* node) :
|
|
378
|
+
typeInfo(ti), refVal(val), symId(id), gNode(node)
|
|
378
379
|
{
|
|
379
380
|
}
|
|
380
381
|
|
|
@@ -172,12 +172,22 @@ const SVFValue* ThreadAPI::getForkedFun(const CallICFGNode *inst) const
|
|
|
172
172
|
return inst->getArgument(2);
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
|
|
176
|
-
/// Note that, it is the sole argument of start routine ( a void* pointer )
|
|
177
|
-
const SVFValue* ThreadAPI::getActualParmAtForkSite(const CallICFGNode *inst) const
|
|
175
|
+
const SVFVar* ThreadAPI::getActualParmAtForkSite(const CallICFGNode* inst) const
|
|
178
176
|
{
|
|
179
|
-
assert(
|
|
180
|
-
|
|
177
|
+
assert(PAG::getPAG()->hasCallSiteArgsMap(inst) && "forksite has no args list!");
|
|
178
|
+
const SVFIR::SVFVarList& csArgList = PAG::getPAG()->getCallSiteArgsList(inst);
|
|
179
|
+
// pthread_create has 4 parameters
|
|
180
|
+
assert(csArgList.size() == 4 && "num of forksite args is not 4");
|
|
181
|
+
return csArgList[3];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const SVFVar* ThreadAPI::getFormalParmOfForkedFun(const SVFFunction* F) const
|
|
185
|
+
{
|
|
186
|
+
assert(PAG::getPAG()->hasFunArgsList(F) && "forked function has no args list!");
|
|
187
|
+
const SVFIR::SVFVarList& funArgList = PAG::getPAG()->getFunArgsList(F);
|
|
188
|
+
// in pthread, forked functions are of type void *()(void *args)
|
|
189
|
+
assert(funArgList.size() == 1 && "num of pthread forked function args is not 1!");
|
|
190
|
+
return funArgList[0];
|
|
181
191
|
}
|
|
182
192
|
|
|
183
193
|
const SVFValue* ThreadAPI::getRetParmAtJoinedSite(const CallICFGNode *inst) const
|