svf-tools 1.0.980 → 1.0.982

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 (50) hide show
  1. package/package.json +1 -1
  2. package/svf/include/AE/Svfexe/AEDetector.h +1 -13
  3. package/svf/include/Graphs/ICFG.h +9 -0
  4. package/svf/include/Graphs/ICFGNode.h +33 -0
  5. package/svf/include/Graphs/VFGNode.h +0 -6
  6. package/svf/include/MSSA/MemRegion.h +2 -2
  7. package/svf/include/MTA/LockAnalysis.h +1 -1
  8. package/svf/include/MTA/MHP.h +1 -2
  9. package/svf/include/MTA/TCT.h +1 -10
  10. package/svf/include/SABER/SaberCondAllocator.h +5 -5
  11. package/svf/include/SVFIR/SVFIR.h +1 -1
  12. package/svf/include/SVFIR/SVFStatements.h +1 -1
  13. package/svf/include/SVFIR/SVFValue.h +21 -16
  14. package/svf/include/Util/SVFBugReport.h +2 -2
  15. package/svf/include/Util/SVFUtil.h +25 -18
  16. package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +1 -2
  17. package/svf/lib/Graphs/ICFG.cpp +41 -10
  18. package/svf/lib/Graphs/IRGraph.cpp +2 -4
  19. package/svf/lib/Graphs/SVFG.cpp +7 -3
  20. package/svf/lib/Graphs/SVFGReadWrite.cpp +2 -2
  21. package/svf/lib/MSSA/MemRegion.cpp +13 -13
  22. package/svf/lib/MSSA/MemSSA.cpp +10 -18
  23. package/svf/lib/MTA/LockAnalysis.cpp +16 -17
  24. package/svf/lib/MTA/MHP.cpp +28 -30
  25. package/svf/lib/MTA/MTA.cpp +2 -3
  26. package/svf/lib/MTA/MTAStat.cpp +2 -4
  27. package/svf/lib/MTA/TCT.cpp +4 -4
  28. package/svf/lib/MemoryModel/PointerAnalysis.cpp +6 -9
  29. package/svf/lib/SABER/DoubleFreeChecker.cpp +1 -1
  30. package/svf/lib/SABER/FileChecker.cpp +2 -5
  31. package/svf/lib/SABER/LeakChecker.cpp +2 -2
  32. package/svf/lib/SABER/ProgSlice.cpp +2 -2
  33. package/svf/lib/SABER/SaberCondAllocator.cpp +7 -8
  34. package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -2
  35. package/svf/lib/SVFIR/SVFIR.cpp +1 -1
  36. package/svf/lib/SVFIR/SVFStatements.cpp +1 -1
  37. package/svf/lib/SVFIR/SVFValue.cpp +1 -10
  38. package/svf/lib/Util/CDGBuilder.cpp +6 -9
  39. package/svf/lib/Util/CallGraphBuilder.cpp +7 -7
  40. package/svf/lib/Util/SVFBugReport.cpp +1 -1
  41. package/svf/lib/Util/SVFUtil.cpp +56 -0
  42. package/svf/lib/Util/ThreadAPI.cpp +1 -2
  43. package/svf-llvm/include/SVF-LLVM/ICFGBuilder.h +16 -6
  44. package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +11 -0
  45. package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +2 -2
  46. package/svf-llvm/lib/ICFGBuilder.cpp +103 -53
  47. package/svf-llvm/lib/LLVMLoopAnalysis.cpp +18 -4
  48. package/svf-llvm/lib/LLVMModule.cpp +16 -3
  49. package/svf-llvm/lib/ObjTypeInference.cpp +6 -2
  50. package/svf-llvm/lib/SVFIRBuilder.cpp +7 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.980",
3
+ "version": "1.0.982",
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": {
@@ -218,21 +218,9 @@ public:
218
218
  */
219
219
  void addBugToReporter(const AEException& e, const ICFGNode* node)
220
220
  {
221
- const SVFInstruction* inst = nullptr;
222
-
223
- // Determine the instruction associated with the ICFG node
224
- if (const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(node))
225
- {
226
- inst = call->getCallSite(); // If the node is a call node, get the call site instruction
227
- }
228
- else
229
- {
230
- inst = node->getSVFStmts().back()->getInst(); // Otherwise, get the last instruction of the node's
231
- // statements
232
- }
233
221
 
234
222
  GenericBug::EventStack eventStack;
235
- SVFBugEvent sourceInstEvent(SVFBugEvent::EventType::SourceInst, inst);
223
+ SVFBugEvent sourceInstEvent(SVFBugEvent::EventType::SourceInst, node);
236
224
  eventStack.push_back(sourceInstEvent); // Add the source instruction event to the event stack
237
225
 
238
226
  if (eventStack.empty())
@@ -198,12 +198,21 @@ public:
198
198
  //@{
199
199
  ICFGNode* getICFGNode(const SVFInstruction* inst);
200
200
 
201
+ /// Whether has the ICFGNode
202
+ bool hasICFGNode(const SVFInstruction* inst);
203
+
201
204
  CallICFGNode* getCallICFGNode(const SVFInstruction* inst);
202
205
 
206
+ CallICFGNode* addCallICFGNode(const SVFInstruction* inst);
207
+
203
208
  RetICFGNode* getRetICFGNode(const SVFInstruction* inst);
204
209
 
210
+ RetICFGNode* addRetICFGNode(const SVFInstruction* inst);
211
+
205
212
  IntraICFGNode* getIntraICFGNode(const SVFInstruction* inst);
206
213
 
214
+ IntraICFGNode* addIntraICFGNode(const SVFInstruction* inst);
215
+
207
216
  FunEntryICFGNode* getFunEntryICFGNode(const SVFFunction* fun);
208
217
 
209
218
  FunExitICFGNode* getFunExitICFGNode(const SVFFunction* fun);
@@ -132,6 +132,8 @@ public:
132
132
 
133
133
  virtual const std::string toString() const;
134
134
 
135
+ virtual const std::string getSourceLoc() const = 0;
136
+
135
137
  void dump() const;
136
138
 
137
139
  protected:
@@ -172,6 +174,11 @@ public:
172
174
  //@}
173
175
 
174
176
  virtual const std::string toString() const;
177
+
178
+ virtual const std::string getSourceLoc() const
179
+ {
180
+ return "Global ICFGNode";
181
+ }
175
182
  };
176
183
 
177
184
  /*!
@@ -218,6 +225,11 @@ public:
218
225
  //@}
219
226
 
220
227
  const std::string toString() const;
228
+
229
+ virtual const std::string getSourceLoc() const
230
+ {
231
+ return inst->getSourceLoc();
232
+ }
221
233
  };
222
234
 
223
235
  class InterICFGNode : public ICFGNode
@@ -252,6 +264,7 @@ public:
252
264
  || node->getNodeKind() == FunRetBlock;
253
265
  }
254
266
  //@}
267
+ virtual const std::string getSourceLoc() const = 0;
255
268
  };
256
269
 
257
270
 
@@ -316,6 +329,11 @@ public:
316
329
  //@}
317
330
 
318
331
  const virtual std::string toString() const;
332
+
333
+ virtual const std::string getSourceLoc() const
334
+ {
335
+ return "function entry: " + fun->getSourceLoc();
336
+ }
319
337
  };
320
338
 
321
339
  /*!
@@ -377,6 +395,11 @@ public:
377
395
  //@}
378
396
 
379
397
  virtual const std::string toString() const;
398
+
399
+ virtual const std::string getSourceLoc() const
400
+ {
401
+ return "function ret: " + fun->getSourceLoc();
402
+ }
380
403
  };
381
404
 
382
405
  /*!
@@ -478,6 +501,11 @@ public:
478
501
  //@}
479
502
 
480
503
  virtual const std::string toString() const;
504
+
505
+ virtual const std::string getSourceLoc() const
506
+ {
507
+ return "CallICFGNode: " + cs->getSourceLoc();
508
+ }
481
509
  };
482
510
 
483
511
 
@@ -554,6 +582,11 @@ public:
554
582
  //@}
555
583
 
556
584
  virtual const std::string toString() const;
585
+
586
+ virtual const std::string getSourceLoc() const
587
+ {
588
+ return "RetICFGNode: " + cs->getSourceLoc();
589
+ }
557
590
  };
558
591
 
559
592
  } // End namespace SVF
@@ -181,12 +181,6 @@ public:
181
181
  || node->getNodeKind() == Store
182
182
  || node->getNodeKind() == Load;
183
183
  }
184
-
185
- inline const SVFInstruction* getInst() const
186
- {
187
- /// should return a valid instruction unless it is a global PAGEdge
188
- return pagEdge->getInst();
189
- }
190
184
  //@}
191
185
 
192
186
  const SVFValue* getValue() const override;
@@ -470,9 +470,9 @@ public:
470
470
  }
471
471
  //@}
472
472
  /// Whether this instruction has SVFIR Edge
473
- bool hasSVFStmtList(const SVFInstruction* inst);
473
+ bool hasSVFStmtList(const ICFGNode* icfgNode);
474
474
  /// Given an instruction, get all its the PAGEdge (statement) in sequence
475
- SVFStmtList& getPAGEdgesFromInst(const SVFInstruction* inst);
475
+ SVFStmtList& getPAGEdgesFromInst(const ICFGNode* node);
476
476
 
477
477
  /// getModRefInfo APIs
478
478
  //@{
@@ -339,7 +339,7 @@ private:
339
339
  void handleIntra(const CxtStmt& cts);
340
340
 
341
341
  /// Handle call relations
342
- void handleCallRelation(CxtLockProc& clp, const CallGraphEdge* cgEdge, CallSite call);
342
+ void handleCallRelation(CxtLockProc& clp, const CallGraphEdge* cgEdge, const CallICFGNode* call);
343
343
 
344
344
  /// Return true it a lock matches an unlock
345
345
  bool isAliasedLocks(const CxtLock& cl1, const CxtLock& cl2)
@@ -341,8 +341,7 @@ public:
341
341
  NodeID parentTid = tct->getParentThread(tid);
342
342
  const CxtThread& parentct = tct->getTCTNode(parentTid)->getCxtThread();
343
343
  const SVFFunction* parentRoutine = tct->getStartRoutineOfCxtThread(parentct);
344
- const SVFInstruction* inst = parentRoutine->getExitBB()->back();
345
- return tct->getICFGNode(inst);
344
+ return parentRoutine->getExitBB()->back();
346
345
  }
347
346
 
348
347
  /// Get loop for join site
@@ -167,15 +167,6 @@ public:
167
167
  {
168
168
  destroy();
169
169
  }
170
- /// Get CallICFGNode given inst
171
- CallICFGNode* getCallICFGNode(const SVFInstruction* inst)
172
- {
173
- return pta->getICFG()->getCallICFGNode(inst);
174
- }
175
- const ICFGNode* getICFGNode(const SVFInstruction* inst)
176
- {
177
- return pta->getICFG()->getICFGNode(inst);
178
- }
179
170
 
180
171
  /// Get SVFFModule
181
172
  SVFModule* getSVFModule() const
@@ -497,7 +488,7 @@ private:
497
488
  //@}
498
489
 
499
490
  /// Handle call relations
500
- void handleCallRelation(CxtThreadProc& ctp, const CallGraphEdge* cgEdge, CallSite call);
491
+ void handleCallRelation(CxtThreadProc& ctp, const CallGraphEdge* cgEdge, const CallICFGNode* call);
501
492
 
502
493
  /// Get or create a tct node based on CxtThread
503
494
  //@{
@@ -49,7 +49,7 @@ class SaberCondAllocator
49
49
  public:
50
50
 
51
51
  typedef Z3Expr Condition; /// z3 condition
52
- typedef Map<u32_t, const SVFInstruction *> IndexToTermInstMap; /// id to instruction map for z3
52
+ typedef Map<u32_t, const ICFGNode*> IndexToTermInstMap; /// id to instruction map for z3
53
53
  typedef Map<u32_t,Condition> CondPosMap; ///< map a branch to its Condition
54
54
  typedef Map<const SVFBasicBlock*, CondPosMap > BBCondMap; /// map bb to a Condition
55
55
  typedef Set<const SVFBasicBlock*> BasicBlockSet;
@@ -118,21 +118,21 @@ public:
118
118
  }
119
119
 
120
120
  /// Allocate a new condition
121
- Condition newCond(const SVFInstruction* inst);
121
+ Condition newCond(const ICFGNode* inst);
122
122
 
123
123
  /// Perform path allocation
124
124
  void allocate(const SVFModule* module);
125
125
 
126
126
  /// Get/Set instruction based on Z3 expression id
127
127
  //{@
128
- inline const SVFInstruction* getCondInst(u32_t id) const
128
+ inline const ICFGNode* getCondInst(u32_t id) const
129
129
  {
130
130
  IndexToTermInstMap::const_iterator it = idToTermInstMap.find(id);
131
131
  assert(it != idToTermInstMap.end() && "this should be a fresh condition");
132
132
  return it->second;
133
133
  }
134
134
 
135
- inline void setCondInst(const Condition &condition, const SVFInstruction* inst)
135
+ inline void setCondInst(const Condition &condition, const ICFGNode* inst)
136
136
  {
137
137
  assert(idToTermInstMap.find(condition.id()) == idToTermInstMap.end() && "this should be a fresh condition");
138
138
  idToTermInstMap[condition.id()] = inst;
@@ -235,7 +235,7 @@ public:
235
235
 
236
236
 
237
237
  /// mark neg Z3 expression
238
- inline void setNegCondInst(const Condition &condition, const SVFInstruction* inst)
238
+ inline void setNegCondInst(const Condition &condition, const ICFGNode* inst)
239
239
  {
240
240
  setCondInst(condition, inst);
241
241
  negConds.set(condition.id());
@@ -658,7 +658,7 @@ private:
658
658
  /// Add Load edge
659
659
  LoadStmt* addLoadStmt(NodeID src, NodeID dst);
660
660
  /// Add Store edge
661
- StoreStmt* addStoreStmt(NodeID src, NodeID dst, const IntraICFGNode* val);
661
+ StoreStmt* addStoreStmt(NodeID src, NodeID dst, const ICFGNode* val);
662
662
  /// Add Call edge
663
663
  CallPE* addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs,
664
664
  const FunEntryICFGNode* entry);
@@ -478,7 +478,7 @@ public:
478
478
  //@}
479
479
 
480
480
  /// constructor
481
- StoreStmt(SVFVar* s, SVFVar* d, const IntraICFGNode* st);
481
+ StoreStmt(SVFVar* s, SVFVar* d, const ICFGNode* st);
482
482
 
483
483
  virtual const std::string toString() const override;
484
484
  };
@@ -524,6 +524,8 @@ public:
524
524
  }
525
525
  };
526
526
 
527
+ class ICFGNode;
528
+
527
529
  class SVFBasicBlock : public SVFValue
528
530
  {
529
531
  friend class LLVMModuleSet;
@@ -531,21 +533,26 @@ class SVFBasicBlock : public SVFValue
531
533
  friend class SVFIRReader;
532
534
  friend class SVFIRBuilder;
533
535
  friend class SVFFunction;
536
+ friend class ICFGBuilder;
537
+ friend class ICFG;
534
538
 
535
539
  public:
536
- typedef std::vector<const SVFInstruction*>::const_iterator const_iterator;
540
+ typedef std::vector<const ICFGNode*>::const_iterator const_iterator;
537
541
 
538
542
  private:
539
- std::vector<const SVFInstruction*> allInsts; ///< all Instructions in this BasicBlock
543
+ std::vector<const ICFGNode*> allICFGNodes; ///< all ICFGNodes in this BasicBlock
540
544
  std::vector<const SVFBasicBlock*> succBBs; ///< all successor BasicBlocks of this BasicBlock
541
545
  std::vector<const SVFBasicBlock*> predBBs; ///< all predecessor BasicBlocks of this BasicBlock
542
546
  const SVFFunction* fun; /// Function where this BasicBlock is
543
547
 
544
548
  protected:
545
549
  ///@{ attributes to be set only through Module builders e.g., LLVMModule
546
- inline void addInstruction(const SVFInstruction* inst)
550
+
551
+ inline void addICFGNode(const ICFGNode* icfgNode)
547
552
  {
548
- allInsts.push_back(inst);
553
+ assert(std::find(getICFGNodeList().begin(), getICFGNodeList().end(),
554
+ icfgNode) == getICFGNodeList().end() && "duplicated icfgnode");
555
+ allICFGNodes.push_back(icfgNode);
549
556
  }
550
557
 
551
558
  inline void addSuccBasicBlock(const SVFBasicBlock* succ)
@@ -570,19 +577,19 @@ public:
570
577
  return node->getKind() == SVFBB;
571
578
  }
572
579
 
573
- inline const std::vector<const SVFInstruction*>& getInstructionList() const
580
+ inline const std::vector<const ICFGNode*>& getICFGNodeList() const
574
581
  {
575
- return allInsts;
582
+ return allICFGNodes;
576
583
  }
577
584
 
578
585
  inline const_iterator begin() const
579
586
  {
580
- return allInsts.begin();
587
+ return allICFGNodes.begin();
581
588
  }
582
589
 
583
590
  inline const_iterator end() const
584
591
  {
585
- return allInsts.end();
592
+ return allICFGNodes.end();
586
593
  }
587
594
 
588
595
  inline const SVFFunction* getParent() const
@@ -595,20 +602,18 @@ public:
595
602
  return fun;
596
603
  }
597
604
 
598
- inline const SVFInstruction* front() const
605
+ inline const ICFGNode* front() const
599
606
  {
600
- return allInsts.front();
607
+ assert(!allICFGNodes.empty() && "bb empty?");
608
+ return allICFGNodes.front();
601
609
  }
602
610
 
603
- inline const SVFInstruction* back() const
611
+ inline const ICFGNode* back() const
604
612
  {
605
- return allInsts.back();
613
+ assert(!allICFGNodes.empty() && "bb empty?");
614
+ return allICFGNodes.back();
606
615
  }
607
616
 
608
- /// Returns the terminator instruction if the block is well formed or null
609
- /// if the block is not well formed.
610
- const SVFInstruction* getTerminator() const;
611
-
612
617
  inline const std::vector<const SVFBasicBlock*>& getSuccessors() const
613
618
  {
614
619
  return succBBs;
@@ -62,10 +62,10 @@ public:
62
62
 
63
63
  protected:
64
64
  u32_t typeAndInfoFlag;
65
- const SVFInstruction *eventInst;
65
+ const ICFGNode *eventInst;
66
66
 
67
67
  public:
68
- SVFBugEvent(u32_t typeAndInfoFlag, const SVFInstruction *eventInst): typeAndInfoFlag(typeAndInfoFlag), eventInst(eventInst) { };
68
+ SVFBugEvent(u32_t typeAndInfoFlag, const ICFGNode *eventInst): typeAndInfoFlag(typeAndInfoFlag), eventInst(eventInst) { };
69
69
  virtual ~SVFBugEvent() = default;
70
70
 
71
71
  inline u32_t getEventType() const
@@ -168,6 +168,8 @@ void dumpPointsToList(const PointsToList& ptl);
168
168
 
169
169
  /// Return true if it is an llvm intrinsic instruction
170
170
  bool isIntrinsicInst(const SVFInstruction* inst);
171
+ bool isIntrinsicInst(const ICFGNode* inst);
172
+
171
173
  //@}
172
174
 
173
175
  /// Whether an instruction is a call or invoke instruction
@@ -184,6 +186,10 @@ inline bool isCallSite(const SVFValue* val)
184
186
  return false;
185
187
  }
186
188
 
189
+ bool isCallSite(const ICFGNode* inst);
190
+
191
+ bool isRetInstNode(const ICFGNode* node);
192
+
187
193
  /// Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls
188
194
  inline bool isNonInstricCallSite(const SVFInstruction* inst)
189
195
  {
@@ -192,7 +198,20 @@ inline bool isNonInstricCallSite(const SVFInstruction* inst)
192
198
  return isCallSite(inst);
193
199
  }
194
200
 
195
- /// Return LLVM callsite given an instruction
201
+ /// Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls
202
+ inline bool isNonInstricCallSite(const ICFGNode* inst)
203
+ {
204
+ if(isIntrinsicInst(inst))
205
+ return false;
206
+ return isCallSite(inst);
207
+ }
208
+
209
+
210
+
211
+ /// Return callsite given an instruction
212
+ CallSite getSVFCallSite(const ICFGNode* inst);
213
+
214
+ /// Return callsite given an instruction
196
215
  inline CallSite getSVFCallSite(const SVFInstruction* inst)
197
216
  {
198
217
  assert(isCallSite(inst) && "not a callsite?");
@@ -250,6 +269,8 @@ inline const SVFFunction* getCallee(const SVFInstruction *inst)
250
269
  CallSite cs(inst);
251
270
  return getCallee(cs);
252
271
  }
272
+
273
+ const SVFFunction* getCallee(const ICFGNode *inst);
253
274
  //@}
254
275
 
255
276
  /// Given a map mapping points-to sets to a count, adds from into to.
@@ -402,27 +423,20 @@ inline bool isArgOfUncalledFunction(const SVFValue* svfval)
402
423
 
403
424
  /// Return thread fork function
404
425
  //@{
405
- inline const SVFValue* getForkedFun(const CallSite cs)
406
- {
407
- return ThreadAPI::getThreadAPI()->getForkedFun(cs.getInstruction());
408
- }
409
426
  inline const SVFValue* getForkedFun(const SVFInstruction *inst)
410
427
  {
411
428
  return ThreadAPI::getThreadAPI()->getForkedFun(inst);
412
429
  }
413
430
  //@}
414
431
 
415
- /// This function servers a allocation wrapper detector
416
- inline bool isAnAllocationWraper(const SVFInstruction*)
417
- {
418
- return false;
419
- }
420
432
 
421
433
  inline bool isExtCall(const CallSite cs)
422
434
  {
423
435
  return isExtCall(getCallee(cs));
424
436
  }
425
437
 
438
+ bool isExtCall(const ICFGNode* node);
439
+
426
440
  inline bool isExtCall(const SVFInstruction *inst)
427
441
  {
428
442
  return isExtCall(getCallee(inst));
@@ -451,10 +465,7 @@ inline bool isHeapAllocExtCallViaRet(const SVFInstruction *inst)
451
465
  return isPtrTy && isHeapAllocExtFunViaRet(getCallee(inst));
452
466
  }
453
467
 
454
- inline bool isHeapAllocExtCall(const CallSite cs)
455
- {
456
- return isHeapAllocExtCallViaRet(cs) || isHeapAllocExtCallViaArg(cs);
457
- }
468
+ bool isHeapAllocExtCall(const ICFGNode* cs);
458
469
 
459
470
  inline bool isHeapAllocExtCall(const SVFInstruction *inst)
460
471
  {
@@ -477,10 +488,6 @@ inline bool isReallocExtCall(const CallSite cs)
477
488
 
478
489
  /// Return true if this is a thread creation call
479
490
  ///@{
480
- inline bool isThreadForkCall(const CallSite cs)
481
- {
482
- return ThreadAPI::getThreadAPI()->isTDFork(cs.getInstruction());
483
- }
484
491
  inline bool isThreadForkCall(const SVFInstruction *inst)
485
492
  {
486
493
  return ThreadAPI::getThreadAPI()->isTDFork(inst);
@@ -845,9 +845,8 @@ void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode *callNode)
845
845
  FIFOWorkList<const ICFGNode *> instWorklist;
846
846
  for (const SVFBasicBlock * bb: callfun->getReachableBBs())
847
847
  {
848
- for (const SVFInstruction* inst: bb->getInstructionList())
848
+ for (const ICFGNode* node: bb->getICFGNodeList())
849
849
  {
850
- const ICFGNode* node = icfg->getICFGNode(inst);
851
850
  for (const SVFStmt *stmt: node->getSVFStmts())
852
851
  {
853
852
  if (const StoreStmt *store = SVFUtil::dyn_cast<StoreStmt>(stmt))
@@ -119,7 +119,8 @@ const std::string FunExitICFGNode::toString() const
119
119
  rawstr << " {fun: " << fun->getName();
120
120
  // ensure the enclosing function has exit basic block
121
121
  if (!isExtCall(fun) && fun->hasReturn())
122
- rawstr << fun->getExitBB()->front()->getSourceLoc();
122
+ if(const IntraICFGNode* intraICFGNode = dyn_cast<IntraICFGNode>(fun->getExitBB()->front()))
123
+ rawstr << intraICFGNode->getInst()->getSourceLoc();
123
124
  rawstr << "}";
124
125
  for (const SVFStmt *stmt : getSVFStmts())
125
126
  rawstr << "\n" << stmt->toString();
@@ -229,7 +230,6 @@ ICFGNode* ICFG::getICFGNode(const SVFInstruction* inst)
229
230
  node = getCallICFGNode(inst);
230
231
  else if(SVFUtil::isIntrinsicInst(inst))
231
232
  node = getIntraICFGNode(inst);
232
- // assert (false && "associating an intrinsic instruction with an ICFGNode!");
233
233
  else
234
234
  node = getIntraICFGNode(inst);
235
235
 
@@ -237,39 +237,70 @@ ICFGNode* ICFG::getICFGNode(const SVFInstruction* inst)
237
237
  return node;
238
238
  }
239
239
 
240
+ bool ICFG::hasICFGNode(const SVF::SVFInstruction* inst)
241
+ {
242
+ ICFGNode* node;
243
+ if(SVFUtil::isNonInstricCallSite(inst))
244
+ node = getCallBlock(inst);
245
+ else if(SVFUtil::isIntrinsicInst(inst))
246
+ node = getIntraBlock(inst);
247
+ else
248
+ node = getIntraBlock(inst);
249
+
250
+ return node != nullptr;
251
+ }
252
+
240
253
 
241
254
  CallICFGNode* ICFG::getCallICFGNode(const SVFInstruction* inst)
242
255
  {
243
- if(SVFUtil::isCallSite(inst) ==false)
244
- outs() << inst->toString() << "\n";
245
256
  assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
246
257
  assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
247
258
  CallICFGNode* node = getCallBlock(inst);
248
- if(node==nullptr)
249
- node = addCallBlock(inst);
250
259
  assert (node!=nullptr && "no CallICFGNode for this instruction?");
251
260
  return node;
252
261
  }
253
262
 
263
+ CallICFGNode* ICFG::addCallICFGNode(const SVFInstruction* inst)
264
+ {
265
+ assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
266
+ assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
267
+ assert(getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
268
+ return addCallBlock(inst);
269
+ }
270
+
254
271
  RetICFGNode* ICFG::getRetICFGNode(const SVFInstruction* inst)
255
272
  {
256
273
  assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
257
274
  assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
258
275
  RetICFGNode* node = getRetBlock(inst);
259
- if(node==nullptr)
260
- node = addRetBlock(inst);
261
276
  assert (node!=nullptr && "no RetICFGNode for this instruction?");
262
277
  return node;
263
278
  }
264
279
 
280
+ RetICFGNode* ICFG::addRetICFGNode(const SVFInstruction* inst)
281
+ {
282
+ assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
283
+ assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
284
+ assert(getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
285
+ return addRetBlock(inst);
286
+ }
287
+
265
288
  IntraICFGNode* ICFG::getIntraICFGNode(const SVFInstruction* inst)
266
289
  {
267
290
  IntraICFGNode* node = getIntraBlock(inst);
268
- if(node==nullptr)
269
- node = addIntraBlock(inst);
291
+ assert (node!=nullptr && "no IntraICFGNode for this instruction?");
270
292
  return node;
271
293
  }
272
294
 
295
+
296
+ IntraICFGNode* ICFG::addIntraICFGNode(const SVFInstruction* inst)
297
+ {
298
+ IntraICFGNode* node = getIntraBlock(inst);
299
+ assert (node==nullptr && "no IntraICFGNode for this instruction?");
300
+ return addIntraBlock(inst);
301
+ }
302
+
303
+
273
304
  /// Add a function entry node
274
305
  FunEntryICFGNode* ICFG::getFunEntryICFGNode(const SVFFunction* fun)
275
306
  {
@@ -273,13 +273,11 @@ struct DOTGraphTraits<IRGraph*> : public DefaultDOTGraphTraits
273
273
  assert(edge && "No edge found!!");
274
274
  if(const CallPE* calledge = SVFUtil::dyn_cast<CallPE>(edge))
275
275
  {
276
- const SVFInstruction* callInst= calledge->getCallSite()->getCallSite();
277
- return callInst->getSourceLoc();
276
+ return calledge->getCallSite()->getSourceLoc();
278
277
  }
279
278
  else if(const RetPE* retedge = SVFUtil::dyn_cast<RetPE>(edge))
280
279
  {
281
- const SVFInstruction* callInst= retedge->getCallSite()->getCallSite();
282
- return callInst->getSourceLoc();
280
+ return retedge->getCallSite()->getSourceLoc();
283
281
  }
284
282
  return "";
285
283
  }
@@ -111,7 +111,11 @@ const std::string MSSAPHISVFGNode::toString() const
111
111
  rawstr << ")\n";
112
112
 
113
113
  rawstr << getResVer()->getMR()->dumpStr();
114
- rawstr << getICFGNode()->getBB()->back()->getSourceLoc();
114
+ if (const IntraICFGNode* intraNode =
115
+ dyn_cast<IntraICFGNode>(getICFGNode()->getBB()->back()))
116
+ {
117
+ rawstr << intraNode->getInst()->getSourceLoc();
118
+ }
115
119
  return rawstr.str();
116
120
  }
117
121
 
@@ -271,8 +275,8 @@ void SVFG::addSVFGNodesForAddrTakenVars()
271
275
  for(PHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
272
276
  {
273
277
  MemSSA::PHI* phi = *pi;
274
- const SVFInstruction* inst = phi->getBasicBlock()->front();
275
- addIntraMSSAPHISVFGNode(pag->getICFG()->getICFGNode(inst), phi->opVerBegin(), phi->opVerEnd(),phi->getResVer(), totalVFGNode++);
278
+ const ICFGNode* inst = phi->getBasicBlock()->front();
279
+ addIntraMSSAPHISVFGNode(const_cast<ICFGNode*>(inst), phi->opVerBegin(), phi->opVerEnd(),phi->getResVer(), totalVFGNode++);
276
280
  }
277
281
  }
278
282
  /// initialize memory SSA entry chi nodes
@@ -100,8 +100,8 @@ void SVFG::writeToFile(const string& filename)
100
100
  // opvers
101
101
  f << " >= MVER: {";
102
102
  f << *phiNode->getResVer();
103
- const SVFInstruction* inst = phiNode->getICFGNode()->getBB()->front();
104
- f << "} >= ICFGNodeID: " << pag->getICFG()->getICFGNode(inst)->getId();
103
+ const ICFGNode* inst = phiNode->getICFGNode()->getBB()->front();
104
+ f << "} >= ICFGNodeID: " << inst->getId();
105
105
  f << " >= OPVers: {";
106
106
  for (auto x: opvers)
107
107
  {