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.
Files changed (59) hide show
  1. package/package.json +1 -1
  2. package/svf/include/Graphs/CDG.h +18 -1
  3. package/svf/include/Graphs/CFLGraph.h +19 -1
  4. package/svf/include/Graphs/CHG.h +19 -1
  5. package/svf/include/Graphs/CallGraph.h +19 -1
  6. package/svf/include/Graphs/ConsGNode.h +19 -1
  7. package/svf/include/Graphs/GenericGraph.h +243 -17
  8. package/svf/include/Graphs/ICFG.h +0 -96
  9. package/svf/include/Graphs/ICFGNode.h +55 -22
  10. package/svf/include/Graphs/SVFG.h +2 -2
  11. package/svf/include/Graphs/SVFGNode.h +5 -17
  12. package/svf/include/Graphs/SVFGOPT.h +2 -1
  13. package/svf/include/Graphs/ThreadCallGraph.h +5 -4
  14. package/svf/include/Graphs/VFG.h +2 -2
  15. package/svf/include/Graphs/VFGNode.h +99 -26
  16. package/svf/include/MTA/TCT.h +19 -1
  17. package/svf/include/MemoryModel/PointerAnalysis.h +1 -1
  18. package/svf/include/MemoryModel/PointerAnalysisImpl.h +4 -0
  19. package/svf/include/SABER/SaberCondAllocator.h +2 -2
  20. package/svf/include/SVFIR/SVFFileSystem.h +1 -1
  21. package/svf/include/SVFIR/SVFIR.h +2 -2
  22. package/svf/include/SVFIR/SVFVariables.h +68 -38
  23. package/svf/include/SVFIR/SymbolTableInfo.h +11 -1
  24. package/svf/include/Util/SVFUtil.h +1 -1
  25. package/svf/include/Util/ThreadAPI.h +8 -2
  26. package/svf/include/WPA/Andersen.h +26 -13
  27. package/svf/include/WPA/Steensgaard.h +10 -20
  28. package/svf/include/WPA/TypeAnalysis.h +10 -3
  29. package/svf/lib/AE/Svfexe/AEDetector.cpp +4 -2
  30. package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +10 -12
  31. package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +2 -0
  32. package/svf/lib/DDA/ContextDDA.cpp +12 -8
  33. package/svf/lib/Graphs/ICFG.cpp +9 -93
  34. package/svf/lib/Graphs/SVFG.cpp +1 -1
  35. package/svf/lib/Graphs/ThreadCallGraph.cpp +10 -2
  36. package/svf/lib/Graphs/VFG.cpp +2 -4
  37. package/svf/lib/MSSA/MemRegion.cpp +2 -2
  38. package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +37 -0
  39. package/svf/lib/SABER/LeakChecker.cpp +1 -2
  40. package/svf/lib/SABER/SaberCondAllocator.cpp +13 -16
  41. package/svf/lib/SABER/SaberSVFGBuilder.cpp +2 -2
  42. package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -6
  43. package/svf/lib/SVFIR/SVFVariables.cpp +3 -0
  44. package/svf/lib/SVFIR/SymbolTableInfo.cpp +3 -2
  45. package/svf/lib/Util/ThreadAPI.cpp +15 -5
  46. package/svf/lib/WPA/Andersen.cpp +205 -151
  47. package/svf/lib/WPA/Steensgaard.cpp +1 -163
  48. package/svf-llvm/include/SVF-LLVM/DCHG.h +1 -1
  49. package/svf-llvm/include/SVF-LLVM/ICFGBuilder.h +93 -23
  50. package/svf-llvm/include/SVF-LLVM/LLVMModule.h +84 -0
  51. package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +15 -0
  52. package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +19 -12
  53. package/svf-llvm/lib/ICFGBuilder.cpp +125 -54
  54. package/svf-llvm/lib/LLVMLoopAnalysis.cpp +6 -11
  55. package/svf-llvm/lib/LLVMModule.cpp +54 -0
  56. package/svf-llvm/lib/LLVMUtil.cpp +15 -0
  57. package/svf-llvm/lib/SVFIRBuilder.cpp +92 -76
  58. package/svf-llvm/lib/SVFIRExtAPI.cpp +5 -5
  59. package/svf-llvm/lib/SymbolTableBuilder.cpp +4 -4
@@ -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* b = getFunEntryBlock(fun);
315
- if (b == nullptr)
316
- return addFunEntryBlock(fun);
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* b = getFunExitBlock(fun);
324
- if (b == nullptr)
325
- return addFunExitBlock(fun);
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
- const CallICFGNode* callBlock = iter->first;
508
- const SVFInstruction* cs = callBlock->getCallSite();
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
- CallICFGNode* callBlockNode = getCallICFGNode(cs);
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);
@@ -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 = pag->getICFG()->getRetICFGNode(callICFGNode->getCallSite());
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
- void ThreadCallGraph::addDirectForkEdge(const CallICFGNode* cs)
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
- void ThreadCallGraph::addIndirectForkEdge(const CallICFGNode* cs, const SVFFunction* calleefun)
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
  /*!
@@ -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* retBlockNode = (*it)->getCallSite();
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 = icfg->getRetICFGNode(callBlockNode->getCallSite());
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 = pag->getICFG()->getCallICFGNode(cs->getCallSite());
483
- RetICFGNode* retBlockNode = pag->getICFG()->getRetICFGNode(cs->getCallSite());
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 = icfg->getRetICFGNode(cs->getCallSite());
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
- if (isTestNullExpr(branchStmt->getCondition()->getValue()))
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(branchStmt->getCondition()->getValue()))
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 SVFValue* test) const
345
+ bool SaberCondAllocator::isTestNullExpr(const ICFGNode* test) const
345
346
  {
346
- if(const SVFInstruction* svfInst = SVFUtil::dyn_cast<SVFInstruction>(test))
347
+ if(!test) return false;
348
+ for(const SVFStmt* stmt : PAG::getPAG()->getSVFStmtList(test))
347
349
  {
348
- for(const SVFStmt* stmt : PAG::getPAG()->getSVFStmtList(getICFG()->getICFGNode(svfInst)))
350
+ if(const CmpStmt* cmp = SVFUtil::dyn_cast<CmpStmt>(stmt))
349
351
  {
350
- if(const CmpStmt* cmp = SVFUtil::dyn_cast<CmpStmt>(stmt))
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 SVFValue* test) const
358
+ bool SaberCondAllocator::isTestNotNullExpr(const ICFGNode* test) const
360
359
  {
361
- if(const SVFInstruction* svfInst = SVFUtil::dyn_cast<SVFInstruction>(test))
360
+ if(!test) return false;
361
+ for(const SVFStmt* stmt : PAG::getPAG()->getSVFStmtList(test))
362
362
  {
363
- for(const SVFStmt* stmt : PAG::getPAG()->getSVFStmtList(getICFG()->getICFGNode(svfInst)))
363
+ if(const CmpStmt* cmp = SVFUtil::dyn_cast<CmpStmt>(stmt))
364
364
  {
365
- if(const CmpStmt* cmp = SVFUtil::dyn_cast<CmpStmt>(stmt))
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
- const SVFCallInst* inst = SVFUtil::dyn_cast<SVFCallInst>(pag->getGNode(baseId)->getValue());
141
- if(inst && SVFUtil::isExtCall(pag->getICFG()->getCallICFGNode(inst)))
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
@@ -73,6 +73,9 @@ SVFVar::SVFVar(const SVFValue* val, NodeID i, PNODEK k) :
73
73
  isPtr = val->getType()->isPointerTy();
74
74
  break;
75
75
  }
76
+ default:
77
+ assert(false && "var not handled");
78
+ break;
76
79
  }
77
80
  }
78
81
 
@@ -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
- /// Return the forth argument of the call,
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(isTDFork(inst) && "not a thread fork function!");
180
- return inst->getArgument(3);
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