svf-tools 1.0.983 → 1.0.985

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 (45) hide show
  1. package/package.json +1 -1
  2. package/svf/include/AE/Svfexe/AbstractInterpretation.h +1 -1
  3. package/svf/include/CFL/CFLAlias.h +3 -3
  4. package/svf/include/Graphs/CHG.h +13 -31
  5. package/svf/include/Graphs/ICFG.h +2 -2
  6. package/svf/include/Graphs/ICFGEdge.h +4 -16
  7. package/svf/include/Graphs/ICFGNode.h +58 -0
  8. package/svf/include/Graphs/ThreadCallGraph.h +6 -6
  9. package/svf/include/MTA/MHP.h +3 -3
  10. package/svf/include/MTA/TCT.h +1 -1
  11. package/svf/include/SVFIR/SVFFileSystem.h +0 -2
  12. package/svf/include/SVFIR/SVFValue.h +0 -131
  13. package/svf/include/Util/SVFUtil.h +20 -37
  14. package/svf/include/Util/ThreadAPI.h +5 -26
  15. package/svf/include/WPA/Andersen.h +3 -3
  16. package/svf/include/WPA/Steensgaard.h +3 -3
  17. package/svf/include/WPA/WPAPass.h +3 -3
  18. package/svf/lib/AE/Svfexe/AEDetector.cpp +14 -18
  19. package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +66 -94
  20. package/svf/lib/CFL/CFLAlias.cpp +11 -12
  21. package/svf/lib/DDA/DDAClient.cpp +2 -2
  22. package/svf/lib/Graphs/CHG.cpp +33 -9
  23. package/svf/lib/Graphs/ICFG.cpp +13 -10
  24. package/svf/lib/MSSA/MemRegion.cpp +3 -3
  25. package/svf/lib/MTA/MHP.cpp +1 -1
  26. package/svf/lib/MemoryModel/PointerAnalysis.cpp +21 -23
  27. package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +2 -2
  28. package/svf/lib/SABER/SaberCondAllocator.cpp +1 -1
  29. package/svf/lib/SABER/SaberSVFGBuilder.cpp +1 -1
  30. package/svf/lib/SVFIR/SVFFileSystem.cpp +2 -20
  31. package/svf/lib/Util/SVFUtil.cpp +34 -18
  32. package/svf/lib/Util/ThreadAPI.cpp +32 -15
  33. package/svf/lib/WPA/Andersen.cpp +8 -9
  34. package/svf/lib/WPA/AndersenSCD.cpp +1 -2
  35. package/svf/lib/WPA/Steensgaard.cpp +8 -12
  36. package/svf/lib/WPA/TypeAnalysis.cpp +2 -3
  37. package/svf/lib/WPA/WPAPass.cpp +6 -13
  38. package/svf-llvm/include/SVF-LLVM/DCHG.h +7 -7
  39. package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +0 -8
  40. package/svf-llvm/lib/CHGBuilder.cpp +4 -4
  41. package/svf-llvm/lib/DCHG.cpp +8 -7
  42. package/svf-llvm/lib/ICFGBuilder.cpp +2 -2
  43. package/svf-llvm/lib/LLVMModule.cpp +0 -2
  44. package/svf-llvm/lib/LLVMUtil.cpp +0 -58
  45. package/svf-llvm/lib/SVFIRExtAPI.cpp +2 -2
@@ -29,6 +29,7 @@
29
29
 
30
30
  #include "Graphs/CHG.h"
31
31
  #include "Util/SVFUtil.h"
32
+ #include "Graphs/ICFG.h"
32
33
 
33
34
  using namespace SVF;
34
35
  using namespace SVFUtil;
@@ -48,16 +49,16 @@ static bool hasEdge(const CHNode *src, const CHNode *dst,
48
49
  return false;
49
50
  }
50
51
 
51
- static bool checkArgTypes(CallSite cs, const SVFFunction* fn)
52
+ static bool checkArgTypes(const SVFCallInst* cs, const SVFFunction* fn)
52
53
  {
53
54
 
54
55
  // here we skip the first argument (i.e., this pointer)
55
- u32_t arg_size = (fn->arg_size() > cs.arg_size()) ? cs.arg_size(): fn->arg_size();
56
+ u32_t arg_size = (fn->arg_size() > cs->arg_size()) ? cs->arg_size(): fn->arg_size();
56
57
  if(arg_size > 1)
57
58
  {
58
59
  for (unsigned i = 1; i < arg_size; i++)
59
60
  {
60
- auto cs_arg = cs.getArgOperand(i);
61
+ auto cs_arg = cs->getArgOperand(i);
61
62
  auto fn_arg = fn->getArg(i);
62
63
  if (cs_arg->getType() != fn_arg->getType())
63
64
  {
@@ -69,6 +70,29 @@ static bool checkArgTypes(CallSite cs, const SVFFunction* fn)
69
70
  return true;
70
71
  }
71
72
 
73
+ bool CHGraph::csHasVtblsBasedonCHA(const CallICFGNode* cs)
74
+ {
75
+ CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs->getCallSite());
76
+ return it != csToCHAVtblsMap.end();
77
+ }
78
+ bool CHGraph::csHasVFnsBasedonCHA(const CallICFGNode* cs)
79
+ {
80
+ CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs->getCallSite());
81
+ return it != csToCHAVFnsMap.end();
82
+ }
83
+ const VTableSet& CHGraph::getCSVtblsBasedonCHA(const CallICFGNode* cs)
84
+ {
85
+ CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs->getCallSite());
86
+ assert(it != csToCHAVtblsMap.end() && "cs does not have vtabls based on CHA.");
87
+ return it->second;
88
+ }
89
+ const VFunSet& CHGraph::getCSVFsBasedonCHA(const CallICFGNode* cs)
90
+ {
91
+ CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs->getCallSite());
92
+ assert(it != csToCHAVFnsMap.end() && "cs does not have vfns based on CHA.");
93
+ return it->second;
94
+ }
95
+
72
96
  void CHGraph::addEdge(const string className, const string baseClassName,
73
97
  CHEdge::CHEDGETYPE edgeType)
74
98
  {
@@ -96,13 +120,13 @@ CHNode *CHGraph::getNode(const string name) const
96
120
  * Get virtual functions for callsite "cs" based on vtbls (calculated
97
121
  * based on pointsto set)
98
122
  */
99
- void CHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &virtualFunctions)
123
+ void CHGraph::getVFnsFromVtbls(const SVFCallInst* callsite, const VTableSet &vtbls, VFunSet &virtualFunctions)
100
124
  {
101
-
125
+ const SVFVirtualCallInst* cs = SVFUtil::cast<SVFVirtualCallInst>(callsite);
102
126
  /// get target virtual functions
103
- size_t idx = cs.getFunIdxInVtable();
127
+ size_t idx = cs->getFunIdxInVtable();
104
128
  /// get the function name of the virtual callsite
105
- string funName = cs.getFunNameOfVirtualCall();
129
+ string funName = cs->getFunNameOfVirtualCall();
106
130
  for (const SVFGlobalValue *vt : vtbls)
107
131
  {
108
132
  const CHNode *child = getNode(vt->getName());
@@ -114,8 +138,8 @@ void CHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &vir
114
138
  feit = vfns.end(); fit != feit; ++fit)
115
139
  {
116
140
  const SVFFunction* callee = *fit;
117
- if (cs.arg_size() == callee->arg_size() ||
118
- (cs.isVarArg() && callee->isVarArg()))
141
+ if (cs->arg_size() == callee->arg_size() ||
142
+ (cs->isVarArg() && callee->isVarArg()))
119
143
  {
120
144
 
121
145
  // if argument types do not match
@@ -179,7 +179,7 @@ const std::string CallCFGEdge::toString() const
179
179
  std::string str;
180
180
  std::stringstream rawstr(str);
181
181
  rawstr << "CallCFGEdge " << " [ICFGNode";
182
- rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " << cs->toString() << "\t";
182
+ rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " << getSrcNode()->toString() << "\t";
183
183
  return rawstr.str();
184
184
  }
185
185
 
@@ -188,7 +188,7 @@ const std::string RetCFGEdge::toString() const
188
188
  std::string str;
189
189
  std::stringstream rawstr(str);
190
190
  rawstr << "RetCFGEdge " << " [ICFGNode";
191
- rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " << cs->toString() << "\t";
191
+ rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " << getDstNode()->toString() << "\t";
192
192
  return rawstr.str();
193
193
  }
194
194
 
@@ -438,7 +438,7 @@ ICFGEdge* ICFG::addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, co
438
438
  /*!
439
439
  * Add interprocedural call edges between two nodes
440
440
  */
441
- ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstruction* cs)
441
+ ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode)
442
442
  {
443
443
  ICFGEdge* edge = hasInterICFGEdge(srcNode,dstNode, ICFGEdge::CallCF);
444
444
  if (edge != nullptr)
@@ -448,7 +448,7 @@ ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstr
448
448
  }
449
449
  else
450
450
  {
451
- CallCFGEdge* callEdge = new CallCFGEdge(srcNode,dstNode,cs);
451
+ CallCFGEdge* callEdge = new CallCFGEdge(srcNode,dstNode);
452
452
  return (addICFGEdge(callEdge) ? callEdge : nullptr);
453
453
  }
454
454
  }
@@ -456,7 +456,7 @@ ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstr
456
456
  /*!
457
457
  * Add interprocedural return edges between two nodes
458
458
  */
459
- ICFGEdge* ICFG::addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstruction* cs)
459
+ ICFGEdge* ICFG::addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode)
460
460
  {
461
461
  ICFGEdge* edge = hasInterICFGEdge(srcNode, dstNode, ICFGEdge::RetCF);
462
462
  if (edge != nullptr)
@@ -466,7 +466,7 @@ ICFGEdge* ICFG::addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstru
466
466
  }
467
467
  else
468
468
  {
469
- RetCFGEdge* retEdge = new RetCFGEdge(srcNode,dstNode,cs);
469
+ RetCFGEdge* retEdge = new RetCFGEdge(srcNode,dstNode);
470
470
  return (addICFGEdge(retEdge) ? retEdge : nullptr);
471
471
  }
472
472
  }
@@ -513,7 +513,7 @@ void ICFG::updateCallGraph(CallGraph* callgraph)
513
513
  {
514
514
  FunEntryICFGNode* calleeEntryNode = getFunEntryBlock(callee);
515
515
  FunExitICFGNode* calleeExitNode = getFunExitBlock(callee);
516
- if(ICFGEdge* callEdge = addCallEdge(callBlockNode, calleeEntryNode, cs))
516
+ if(ICFGEdge* callEdge = addCallEdge(callBlockNode, calleeEntryNode))
517
517
  {
518
518
  for (const SVFStmt *stmt : callBlockNode->getSVFStmts())
519
519
  {
@@ -524,7 +524,7 @@ void ICFG::updateCallGraph(CallGraph* callgraph)
524
524
  }
525
525
  }
526
526
  }
527
- if(ICFGEdge* retEdge = addRetEdge(calleeExitNode, retBlockNode, cs))
527
+ if(ICFGEdge* retEdge = addRetEdge(calleeExitNode, retBlockNode))
528
528
  {
529
529
  for (const SVFStmt *stmt : retBlockNode->getSVFStmts())
530
530
  {
@@ -650,9 +650,12 @@ struct DOTGraphTraits<ICFG*> : public DOTGraphTraits<SVFIR*>
650
650
  std::string str;
651
651
  std::stringstream rawstr(str);
652
652
  if (CallCFGEdge* dirCall = SVFUtil::dyn_cast<CallCFGEdge>(edge))
653
- rawstr << dirCall->getCallSite();
653
+ rawstr << dirCall->getSrcNode();
654
654
  else if (RetCFGEdge* dirRet = SVFUtil::dyn_cast<RetCFGEdge>(edge))
655
- rawstr << dirRet->getCallSite();
655
+ {
656
+ if(RetICFGNode* ret = SVFUtil::dyn_cast<RetICFGNode>(dirRet->getDstNode()))
657
+ rawstr << ret->getCallICFGNode();
658
+ }
656
659
 
657
660
  return rawstr.str();
658
661
  }
@@ -601,7 +601,7 @@ bool MRGenerator::isNonLocalObject(NodeID id, const SVFFunction* curFun) const
601
601
  bool MRGenerator::handleCallsiteModRef(NodeBS& mod, NodeBS& ref, const CallICFGNode* cs, const SVFFunction* callee)
602
602
  {
603
603
  /// if a callee is a heap allocator function, then its mod set of this callsite is the heap object.
604
- if(isHeapAllocExtCall(cs->getCallSite()))
604
+ if(isHeapAllocExtCall(cs))
605
605
  {
606
606
  SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs);
607
607
  for (SVFStmtList::const_iterator bit = pagEdgeList.begin(),
@@ -667,7 +667,7 @@ void MRGenerator::modRefAnalysis(CallGraphNode* callGraphNode, WorkList& worklis
667
667
  */
668
668
  NodeBS MRGenerator::getModInfoForCall(const CallICFGNode* cs)
669
669
  {
670
- if (isExtCall(cs->getCallSite()) && !isHeapAllocExtCall(cs->getCallSite()))
670
+ if (isExtCall(cs) && !isHeapAllocExtCall(cs))
671
671
  {
672
672
  SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs);
673
673
  NodeBS mods;
@@ -691,7 +691,7 @@ NodeBS MRGenerator::getModInfoForCall(const CallICFGNode* cs)
691
691
  */
692
692
  NodeBS MRGenerator::getRefInfoForCall(const CallICFGNode* cs)
693
693
  {
694
- if (isExtCall(cs->getCallSite()) && !isHeapAllocExtCall(cs->getCallSite()))
694
+ if (isExtCall(cs) && !isHeapAllocExtCall(cs))
695
695
  {
696
696
  SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs);
697
697
  NodeBS refs;
@@ -819,7 +819,7 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
819
819
  const ICFGNode* forkSite = tct->getTCTNode(rootTid)->getCxtThread().getThread();
820
820
  const ICFGNode* joinSite = cts.getStmt();
821
821
 
822
- if (isAliasedForkJoin(forkSite, joinSite))
822
+ if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite), SVFUtil::cast<CallICFGNode>(joinSite)))
823
823
  {
824
824
  if (hasJoinLoop(joinSite))
825
825
  {
@@ -320,8 +320,8 @@ void PointerAnalysis::printIndCSTargets(const CallICFGNode* cs, const FunctionSe
320
320
  {
321
321
  outs() << "\nNodeID: " << getFunPtr(cs);
322
322
  outs() << "\nCallSite: ";
323
- outs() << cs->getCallSite()->toString();
324
- outs() << "\tLocation: " << cs->getCallSite()->getSourceLoc();
323
+ outs() << cs->toString();
324
+ outs() << "\tLocation: " << cs->getSourceLoc();
325
325
  outs() << "\t with Targets: ";
326
326
 
327
327
  if (!targets.empty())
@@ -368,8 +368,8 @@ void PointerAnalysis::printIndCSTargets()
368
368
  {
369
369
  outs() << "\nNodeID: " << csIt->second;
370
370
  outs() << "\nCallSite: ";
371
- outs() << cs->getCallSite()->toString();
372
- outs() << "\tLocation: " << cs->getCallSite()->getSourceLoc();
371
+ outs() << cs->toString();
372
+ outs() << "\tLocation: " << cs->getSourceLoc();
373
373
  outs() << "\n\t!!!has no targets!!!\n";
374
374
  }
375
375
  }
@@ -428,8 +428,8 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta
428
428
  */
429
429
  void PointerAnalysis::getVFnsFromCHA(const CallICFGNode* cs, VFunSet &vfns)
430
430
  {
431
- if (chgraph->csHasVFnsBasedonCHA(SVFUtil::getSVFCallSite(cs)))
432
- vfns = chgraph->getCSVFsBasedonCHA(SVFUtil::getSVFCallSite(cs));
431
+ if (chgraph->csHasVFnsBasedonCHA(cs))
432
+ vfns = chgraph->getCSVFsBasedonCHA(cs);
433
433
  }
434
434
 
435
435
  /*
@@ -438,10 +438,10 @@ void PointerAnalysis::getVFnsFromCHA(const CallICFGNode* cs, VFunSet &vfns)
438
438
  void PointerAnalysis::getVFnsFromPts(const CallICFGNode* cs, const PointsTo &target, VFunSet &vfns)
439
439
  {
440
440
 
441
- if (chgraph->csHasVtblsBasedonCHA(SVFUtil::getSVFCallSite(cs)))
441
+ if (chgraph->csHasVtblsBasedonCHA(cs))
442
442
  {
443
443
  Set<const SVFGlobalValue*> vtbls;
444
- const VTableSet &chaVtbls = chgraph->getCSVtblsBasedonCHA(SVFUtil::getSVFCallSite(cs));
444
+ const VTableSet &chaVtbls = chgraph->getCSVtblsBasedonCHA(cs);
445
445
  for (PointsTo::iterator it = target.begin(), eit = target.end(); it != eit; ++it)
446
446
  {
447
447
  const PAGNode *ptdnode = pag->getGNode(*it);
@@ -454,7 +454,7 @@ void PointerAnalysis::getVFnsFromPts(const CallICFGNode* cs, const PointsTo &tar
454
454
  }
455
455
  }
456
456
  }
457
- chgraph->getVFnsFromVtbls(SVFUtil::getSVFCallSite(cs), vtbls, vfns);
457
+ chgraph->getVFnsFromVtbls(SVFUtil::cast<SVFCallInst>(cs->getCallSite()), vtbls, vfns);
458
458
  }
459
459
  }
460
460
 
@@ -471,12 +471,12 @@ void PointerAnalysis::connectVCallToVFns(const CallICFGNode* cs, const VFunSet &
471
471
  callee = callee->getDefFunForMultipleModule();
472
472
  if (getIndCallMap()[cs].count(callee) > 0)
473
473
  continue;
474
- if(SVFUtil::getSVFCallSite(cs).arg_size() == callee->arg_size() ||
475
- (SVFUtil::getSVFCallSite(cs).isVarArg() && callee->isVarArg()))
474
+ if(cs->arg_size() == callee->arg_size() ||
475
+ (cs->isVarArg() && callee->isVarArg()))
476
476
  {
477
477
  newEdges[cs].insert(callee);
478
478
  getIndCallMap()[cs].insert(callee);
479
- const CallICFGNode* callBlockNode = pag->getICFG()->getCallICFGNode(cs->getCallSite());
479
+ const CallICFGNode* callBlockNode = cs;
480
480
  callgraph->addIndirectCallGraphEdge(callBlockNode, cs->getCaller(),callee);
481
481
  }
482
482
  }
@@ -485,7 +485,7 @@ void PointerAnalysis::connectVCallToVFns(const CallICFGNode* cs, const VFunSet &
485
485
  /// Resolve cpp indirect call edges
486
486
  void PointerAnalysis::resolveCPPIndCalls(const CallICFGNode* cs, const PointsTo& target, CallEdgeMap& newEdges)
487
487
  {
488
- assert(SVFUtil::getSVFCallSite(cs).isVirtualCall() && "not cpp virtual call");
488
+ assert(cs->isVirtualCall() && "not cpp virtual call");
489
489
 
490
490
  VFunSet vfns;
491
491
  if (Options::ConnectVCallOnCHA())
@@ -511,11 +511,10 @@ void PointerAnalysis::validateSuccessTests(std::string fun)
511
511
  {
512
512
  if (SVFUtil::getCallee(callNode) == checkFun)
513
513
  {
514
- CallSite cs = SVFUtil::getSVFCallSite(callNode);
515
- assert(cs.getNumArgOperands() == 2
514
+ assert(callNode->getNumArgOperands() == 2
516
515
  && "arguments should be two pointers!!");
517
- const SVFValue* V1 = cs.getArgOperand(0);
518
- const SVFValue* V2 = cs.getArgOperand(1);
516
+ const SVFValue* V1 = callNode->getArgOperand(0);
517
+ const SVFValue* V2 = callNode->getArgOperand(1);
519
518
  AliasResult aliasRes = alias(V1, V2);
520
519
 
521
520
  bool checkSuccessful = false;
@@ -577,11 +576,10 @@ void PointerAnalysis::validateExpectedFailureTests(std::string fun)
577
576
  {
578
577
  if (SVFUtil::getCallee(callNode) == checkFun)
579
578
  {
580
- CallSite call = getSVFCallSite(callNode);
581
- assert(call.arg_size() == 2
579
+ assert(callNode->arg_size() == 2
582
580
  && "arguments should be two pointers!!");
583
- const SVFValue* V1 = call.getArgOperand(0);
584
- const SVFValue* V2 = call.getArgOperand(1);
581
+ const SVFValue* V1 = callNode->getArgOperand(0);
582
+ const SVFValue* V2 = callNode->getArgOperand(1);
585
583
  AliasResult aliasRes = alias(V1, V2);
586
584
 
587
585
  bool expectedFailure = false;
@@ -605,11 +603,11 @@ void PointerAnalysis::validateExpectedFailureTests(std::string fun)
605
603
 
606
604
  if (expectedFailure)
607
605
  outs() << sucMsg("\t EXPECTED-FAILURE :") << fun << " check <id:" << id1 << ", id:" << id2 << "> at ("
608
- << call.getInstruction()->getSourceLoc() << ")\n";
606
+ << callNode->getSourceLoc() << ")\n";
609
607
  else
610
608
  {
611
609
  SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << fun << " check <id:" << id1 << ", id:" << id2 << "> at ("
612
- << call.getInstruction()->getSourceLoc() << ")\n";
610
+ << callNode->getSourceLoc() << ")\n";
613
611
  assert(false && "test case failed!");
614
612
  }
615
613
  }
@@ -495,9 +495,9 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites,
495
495
  {
496
496
  const CallICFGNode* cs = iter->first;
497
497
 
498
- if (SVFUtil::getSVFCallSite(cs).isVirtualCall())
498
+ if (cs->isVirtualCall())
499
499
  {
500
- const SVFValue* vtbl = SVFUtil::getSVFCallSite(cs).getVtablePtr();
500
+ const SVFValue* vtbl = cs->getVtablePtr();
501
501
  assert(pag->hasValueNode(vtbl));
502
502
  NodeID vtblId = pag->getValueNode(vtbl);
503
503
  resolveCPPIndCalls(cs, getPts(vtblId), newEdges);
@@ -428,7 +428,7 @@ void SaberCondAllocator::collectBBCallingProgExit(const SVFBasicBlock &bb)
428
428
  for (const auto& icfgNode: bb.getICFGNodeList())
429
429
  {
430
430
  if (const CallICFGNode* cs = SVFUtil::dyn_cast<CallICFGNode>(icfgNode))
431
- if (SVFUtil::isProgExitCall(cs->getCallSite()))
431
+ if (SVFUtil::isProgExitCall(cs))
432
432
  {
433
433
  const SVFFunction* svfun = bb.getParent();
434
434
  funToExitBBsMap[svfun].insert(&bb);
@@ -138,7 +138,7 @@ PointsTo& SaberSVFGBuilder::CollectPtsChain(BVDataPTAImpl* pta, NodeID id, NodeT
138
138
  if(pta->isFIObjNode(baseId) && pag->getGNode(baseId)->hasValue())
139
139
  {
140
140
  const SVFCallInst* inst = SVFUtil::dyn_cast<SVFCallInst>(pag->getGNode(baseId)->getValue());
141
- if(inst && SVFUtil::isExtCall(inst))
141
+ if(inst && SVFUtil::isExtCall(pag->getICFG()->getCallICFGNode(inst)))
142
142
  {
143
143
  return pts;
144
144
  }
@@ -443,7 +443,6 @@ cJSON* SVFIRWriter::contentToJson(const IntraCFGEdge* edge)
443
443
  cJSON* SVFIRWriter::contentToJson(const CallCFGEdge* edge)
444
444
  {
445
445
  cJSON* root = contentToJson(static_cast<const ICFGEdge*>(edge));
446
- JSON_WRITE_FIELD(root, edge, cs);
447
446
  JSON_WRITE_FIELD(root, edge, callPEs);
448
447
  return root;
449
448
  }
@@ -451,7 +450,6 @@ cJSON* SVFIRWriter::contentToJson(const CallCFGEdge* edge)
451
450
  cJSON* SVFIRWriter::contentToJson(const RetCFGEdge* edge)
452
451
  {
453
452
  cJSON* root = contentToJson(static_cast<const ICFGEdge*>(edge));
454
- JSON_WRITE_FIELD(root, edge, cs);
455
453
  JSON_WRITE_FIELD(root, edge, retPE);
456
454
  return root;
457
455
  }
@@ -571,8 +569,6 @@ cJSON* SVFIRWriter::contentToJson(const SVFInstruction* value)
571
569
  JSON_WRITE_FIELD(root, value, bb);
572
570
  JSON_WRITE_FIELD(root, value, terminator);
573
571
  JSON_WRITE_FIELD(root, value, ret);
574
- JSON_WRITE_FIELD(root, value, succInsts);
575
- JSON_WRITE_FIELD(root, value, predInsts);
576
572
  return root;
577
573
  }
578
574
 
@@ -1179,11 +1175,6 @@ cJSON* SVFIRWriter::toJson(const CHEdge* edge)
1179
1175
  return jsonCreateIndex(chgWriter.getEdgeID(edge));
1180
1176
  }
1181
1177
 
1182
- cJSON* SVFIRWriter::toJson(const CallSite& cs)
1183
- {
1184
- return toJson(cs.getInstruction());
1185
- }
1186
-
1187
1178
  cJSON* SVFIRWriter::toJson(const SVFLoop* loop)
1188
1179
  {
1189
1180
  return jsonCreateIndex(icfgWriter.getSvfLoopID(loop));
@@ -1613,9 +1604,9 @@ ICFGEdge* SVFIRReader::createICFGEdge(GEdgeKind kind)
1613
1604
  case ICFGEdge::IntraCF:
1614
1605
  return new IntraCFGEdge(src, dst);
1615
1606
  case ICFGEdge::CallCF:
1616
- return new CallCFGEdge(src, dst, nullptr);
1607
+ return new CallCFGEdge(src, dst);
1617
1608
  case ICFGEdge::RetCF:
1618
- return new RetCFGEdge(src, dst, nullptr);
1609
+ return new RetCFGEdge(src, dst);
1619
1610
  }
1620
1611
  }
1621
1612
 
@@ -1855,11 +1846,6 @@ void SVFIRReader::readJson(const cJSON* obj, CHEdge*& edge)
1855
1846
  edge = chGraphReader.getEdgePtr(jsonGetNumber(obj));
1856
1847
  }
1857
1848
 
1858
- void SVFIRReader::readJson(const cJSON* obj, CallSite& cs)
1859
- {
1860
- readJson(obj, cs.CB);
1861
- }
1862
-
1863
1849
  void SVFIRReader::readJson(const cJSON* obj, AccessPath& ap)
1864
1850
  {
1865
1851
  ABORT_IFNOT(jsonIsObject(obj), "Expected obj for AccessPath");
@@ -2270,14 +2256,12 @@ void SVFIRReader::fill(const cJSON*& fieldJson, IntraCFGEdge* edge)
2270
2256
  void SVFIRReader::fill(const cJSON*& fieldJson, CallCFGEdge* edge)
2271
2257
  {
2272
2258
  fill(fieldJson, static_cast<ICFGEdge*>(edge));
2273
- JSON_READ_FIELD_FWD(fieldJson, edge, cs);
2274
2259
  JSON_READ_FIELD_FWD(fieldJson, edge, callPEs);
2275
2260
  }
2276
2261
 
2277
2262
  void SVFIRReader::fill(const cJSON*& fieldJson, RetCFGEdge* edge)
2278
2263
  {
2279
2264
  fill(fieldJson, static_cast<ICFGEdge*>(edge));
2280
- JSON_READ_FIELD_FWD(fieldJson, edge, cs);
2281
2265
  JSON_READ_FIELD_FWD(fieldJson, edge, retPE);
2282
2266
  }
2283
2267
 
@@ -2391,8 +2375,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, SVFInstruction* value)
2391
2375
  JSON_READ_FIELD_FWD(fieldJson, value, bb);
2392
2376
  JSON_READ_FIELD_FWD(fieldJson, value, terminator);
2393
2377
  JSON_READ_FIELD_FWD(fieldJson, value, ret);
2394
- JSON_READ_FIELD_FWD(fieldJson, value, succInsts);
2395
- JSON_READ_FIELD_FWD(fieldJson, value, predInsts);
2396
2378
  }
2397
2379
 
2398
2380
  void SVFIRReader::fill(const cJSON*& fieldJson, SVFCallInst* value)
@@ -319,11 +319,10 @@ void SVFUtil::stopAnalysisLimitTimer(bool limitTimerSet)
319
319
  /// for variadic function, callsite arg size must be greater than or equal to callee arg size
320
320
  bool SVFUtil::matchArgs(const CallICFGNode* call, const SVFFunction* callee)
321
321
  {
322
- CallSite cs(call->getCallSite());
323
322
  if (callee->isVarArg() || ThreadAPI::getThreadAPI()->isTDFork(call))
324
- return cs.arg_size() >= callee->arg_size();
323
+ return call->arg_size() >= callee->arg_size();
325
324
  else
326
- return cs.arg_size() == callee->arg_size();
325
+ return call->arg_size() == callee->arg_size();
327
326
  }
328
327
 
329
328
  bool SVFUtil::isCallSite(const ICFGNode* inst)
@@ -331,19 +330,11 @@ bool SVFUtil::isCallSite(const ICFGNode* inst)
331
330
  return SVFUtil::isa<CallICFGNode>(inst);
332
331
  }
333
332
 
334
- CallSite SVFUtil::getSVFCallSite(const ICFGNode* inst)
335
- {
336
- assert(isCallSite(inst) && "not a callsite?");
337
- CallSite cs(cast<CallICFGNode>(inst)->getCallSite());
338
- return cs;
339
- }
340
-
341
333
  bool SVFUtil::isIntrinsicInst(const ICFGNode* inst)
342
334
  {
343
335
  if (const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst))
344
336
  {
345
- CallSite cs(call->getCallSite());
346
- const SVFFunction* func = cs.getCalledFunction();
337
+ const SVFFunction* func = call->getCalledFunction();
347
338
  if (func && func->isIntrinsic())
348
339
  {
349
340
  return true;
@@ -356,22 +347,47 @@ const SVFFunction* SVFUtil::getCallee(const ICFGNode *inst)
356
347
  {
357
348
  if (!isCallSite(inst))
358
349
  return nullptr;
359
- CallSite cs(cast<CallICFGNode>(inst)->getCallSite());
360
- return getCallee(cs);
350
+ const CallICFGNode* call = SVFUtil::cast<CallICFGNode>(inst);
351
+ return call->getCalledFunction();
352
+ }
353
+
354
+ const SVFFunction* SVFUtil::getCallee(const CallICFGNode *inst)
355
+ {
356
+ return inst->getCalledFunction();
361
357
  }
362
358
 
359
+
363
360
  bool SVFUtil::isExtCall(const ICFGNode* node)
364
361
  {
365
362
  if(!isCallSite(node)) return false;
366
- CallSite cs(cast<CallICFGNode>(node)->getCallSite());
367
- return isExtCall(getCallee(cs));
363
+ return isExtCall(getCallee(node));
368
364
  }
369
365
 
370
366
  bool SVFUtil::isHeapAllocExtCall(const ICFGNode* cs)
371
367
  {
372
368
  if(!isCallSite(cs)) return false;
373
- CallSite callSite(cast<CallICFGNode>(cs)->getCallSite());
374
- return isHeapAllocExtCallViaRet(callSite) || isHeapAllocExtCallViaArg(callSite);
369
+ return isHeapAllocExtCallViaRet(cast<CallICFGNode>(cs)) || isHeapAllocExtCallViaArg(cast<CallICFGNode>(cs));
370
+ }
371
+
372
+ bool SVFUtil::isHeapAllocExtCallViaRet(const CallICFGNode* cs)
373
+ {
374
+ bool isPtrTy = cs->getCallSite()->getType()->isPointerTy();
375
+ return isPtrTy && isHeapAllocExtFunViaRet(getCallee(cs));
376
+ }
377
+
378
+ bool SVFUtil::isReallocExtCall(const CallICFGNode* cs)
379
+ {
380
+ bool isPtrTy = cs->getCallSite()->getType()->isPointerTy();
381
+ return isPtrTy && isReallocExtFun(getCallee(cs));
382
+ }
383
+
384
+ bool SVFUtil::isHeapAllocExtCallViaRet(const SVFInstruction *inst)
385
+ {
386
+ bool isPtrTy = inst->getType()->isPointerTy();
387
+ if(const SVFCallInst* call = SVFUtil::dyn_cast<SVFCallInst>(inst))
388
+ return isPtrTy && isHeapAllocExtFunViaRet(call->getCalledFunction());
389
+ else
390
+ return false;
375
391
  }
376
392
 
377
393
  bool SVFUtil::isRetInstNode(const ICFGNode* node)
@@ -129,6 +129,32 @@ void ThreadAPI::init()
129
129
  }
130
130
  }
131
131
 
132
+ const SVFValue* ThreadAPI::getForkedThread(const CallICFGNode *inst) const
133
+ {
134
+ assert(isTDFork(inst) && "not a thread fork function!");
135
+ return inst->getArgument(0);
136
+ }
137
+
138
+ const SVFValue* ThreadAPI::getForkedFun(const CallICFGNode *inst) const
139
+ {
140
+ assert(isTDFork(inst) && "not a thread fork function!");
141
+ return inst->getArgument(2);
142
+ }
143
+
144
+ /// Return the forth argument of the call,
145
+ /// Note that, it is the sole argument of start routine ( a void* pointer )
146
+ const SVFValue* ThreadAPI::getActualParmAtForkSite(const CallICFGNode *inst) const
147
+ {
148
+ assert(isTDFork(inst) && "not a thread fork function!");
149
+ return inst->getArgument(3);
150
+ }
151
+
152
+ const SVFValue* ThreadAPI::getRetParmAtJoinedSite(const CallICFGNode *inst) const
153
+ {
154
+ assert(isTDJoin(inst) && "not a thread join function!");
155
+ return inst->getArgument(1);
156
+ }
157
+
132
158
  /*!
133
159
  *
134
160
  */
@@ -140,27 +166,18 @@ const SVFFunction* ThreadAPI::getCallee(const ICFGNode *inst) const
140
166
  return nullptr;
141
167
  }
142
168
 
143
- const CallSite ThreadAPI::getSVFCallSite(const ICFGNode *inst) const
169
+ const SVFValue* ThreadAPI::getLockVal(const ICFGNode *cs) const
144
170
  {
145
- assert(SVFUtil::isa<CallICFGNode>(inst) && "not a callsite?");
146
- CallSite cs(SVFUtil::cast<CallICFGNode>(inst)->getCallSite());
147
- return cs;
148
- }
149
-
150
- const SVFValue* ThreadAPI::getLockVal(const ICFGNode *inst) const
151
- {
152
- const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst);
171
+ const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cs);
153
172
  assert(call && "not a call ICFGNode?");
154
173
  assert((isTDAcquire(call) || isTDRelease(call)) && "not a lock acquire or release function");
155
- CallSite cs = getSVFCallSite(call);
156
- return cs.getArgument(0);
174
+ return call->getArgument(0);
157
175
  }
158
176
 
159
- const SVFValue* ThreadAPI::getJoinedThread(const ICFGNode *inst) const
177
+ const SVFValue* ThreadAPI::getJoinedThread(const CallICFGNode *cs) const
160
178
  {
161
- assert(isTDJoin(inst) && "not a thread join function!");
162
- CallSite cs = getSVFCallSite(inst);
163
- const SVFValue* join = cs.getArgument(0);
179
+ assert(isTDJoin(cs) && "not a thread join function!");
180
+ const SVFValue* join = cs->getArgument(0);
164
181
  const SVFVar* var = PAG::getPAG()->getGNode(PAG::getPAG()->getValueNode(join));
165
182
  for(const SVFStmt* stmt : var->getInEdges())
166
183
  {
@@ -661,10 +661,9 @@ bool Andersen::updateCallGraph(const CallSiteToFunPtrMap& callsites)
661
661
  NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge
662
662
  for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it )
663
663
  {
664
- CallSite cs = SVFUtil::getSVFCallSite(it->first);
665
664
  for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit)
666
665
  {
667
- connectCaller2CalleeParams(cs,*cit,cpySrcNodes);
666
+ connectCaller2CalleeParams(it->first,*cit,cpySrcNodes);
668
667
  }
669
668
  }
670
669
  for(NodePairSet::iterator it = cpySrcNodes.begin(), eit = cpySrcNodes.end(); it!=eit; ++it)
@@ -678,10 +677,10 @@ bool Andersen::updateCallGraph(const CallSiteToFunPtrMap& callsites)
678
677
  return (!newEdges.empty());
679
678
  }
680
679
 
681
- void Andersen::heapAllocatorViaIndCall(CallSite cs, NodePairSet &cpySrcNodes)
680
+ void Andersen::heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet &cpySrcNodes)
682
681
  {
683
682
  assert(SVFUtil::getCallee(cs) == nullptr && "not an indirect callsite?");
684
- RetICFGNode* retBlockNode = pag->getICFG()->getRetICFGNode(cs.getInstruction());
683
+ const RetICFGNode* retBlockNode = cs->getRetICFGNode();
685
684
  const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
686
685
  NodeID srcret;
687
686
  CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs);
@@ -692,7 +691,7 @@ void Andersen::heapAllocatorViaIndCall(CallSite cs, NodePairSet &cpySrcNodes)
692
691
  else
693
692
  {
694
693
  NodeID valNode = pag->addDummyValNode();
695
- NodeID objNode = pag->addDummyObjNode(cs.getType());
694
+ NodeID objNode = pag->addDummyObjNode(cs->getCallSite()->getType());
696
695
  addPts(valNode,objNode);
697
696
  callsite2DummyValPN.insert(std::make_pair(cs,valNode));
698
697
  consCG->addConstraintNode(new ConstraintNode(valNode),valNode);
@@ -708,14 +707,14 @@ void Andersen::heapAllocatorViaIndCall(CallSite cs, NodePairSet &cpySrcNodes)
708
707
  /*!
709
708
  * Connect formal and actual parameters for indirect callsites
710
709
  */
711
- void Andersen::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, NodePairSet &cpySrcNodes)
710
+ void Andersen::connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F, NodePairSet &cpySrcNodes)
712
711
  {
713
712
  assert(F);
714
713
 
715
714
  DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs.getInstruction()->toString() << " to callee " << *F << "\n");
716
715
 
717
- CallICFGNode* callBlockNode = pag->getICFG()->getCallICFGNode(cs.getInstruction());
718
- RetICFGNode* retBlockNode = pag->getICFG()->getRetICFGNode(cs.getInstruction());
716
+ const CallICFGNode* callBlockNode = cs;
717
+ const RetICFGNode* retBlockNode = cs->getRetICFGNode();
719
718
 
720
719
  if(SVFUtil::isHeapAllocExtFunViaRet(F) && pag->callsiteHasRet(retBlockNode))
721
720
  {
@@ -795,7 +794,7 @@ void Andersen::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, Nod
795
794
  if(csArgIt != csArgEit)
796
795
  {
797
796
  writeWrnMsg("too many args to non-vararg func.");
798
- writeWrnMsg("(" + cs.getInstruction()->getSourceLoc() + ")");
797
+ writeWrnMsg("(" + cs->getSourceLoc() + ")");
799
798
  }
800
799
  }
801
800
  }