svf-tools 1.0.363 → 1.0.367

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 (197) hide show
  1. package/SVF-doxygen/html/html/AndersenStat_8cpp_source.html +1 -1
  2. package/SVF-doxygen/html/html/Andersen_8h_source.html +1 -1
  3. package/SVF-doxygen/html/html/ConsGNode_8h_source.html +5 -5
  4. package/SVF-doxygen/html/html/ConsG_8cpp_source.html +35 -33
  5. package/SVF-doxygen/html/html/ConsG_8h_source.html +20 -20
  6. package/SVF-doxygen/html/html/DDAClient_8cpp_source.html +1 -1
  7. package/SVF-doxygen/html/html/DDAClient_8h_source.html +1 -1
  8. package/SVF-doxygen/html/html/DDAPass_8cpp_source.html +1 -1
  9. package/SVF-doxygen/html/html/DDAVFSolver_8h_source.html +1 -1
  10. package/SVF-doxygen/html/html/IRAnnotator_8h_source.html +1 -1
  11. package/SVF-doxygen/html/html/IRGraph_8cpp_source.html +1 -1
  12. package/SVF-doxygen/html/html/MTAAnnotator_8cpp_source.html +1 -1
  13. package/SVF-doxygen/html/html/MemRegion_8cpp_source.html +1 -1
  14. package/SVF-doxygen/html/html/PAGBuilderFromFile_8cpp_source.html +2 -2
  15. package/SVF-doxygen/html/html/PointerAnalysisImpl_8cpp_source.html +2 -2
  16. package/SVF-doxygen/html/html/PointerAnalysisImpl_8h_source.html +1 -1
  17. package/SVF-doxygen/html/html/PointerAnalysis_8h_source.html +2 -2
  18. package/SVF-doxygen/html/html/SVFGOPT_8h_source.html +2 -2
  19. package/SVF-doxygen/html/html/SVFG_8cpp_source.html +4 -4
  20. package/SVF-doxygen/html/html/SVFG_8h_source.html +1 -1
  21. package/SVF-doxygen/html/html/SVFIRBuilder_8cpp_source.html +9 -6
  22. package/SVF-doxygen/html/html/SVFIRBuilder_8h_source.html +70 -62
  23. package/SVF-doxygen/html/html/SVFIR_8cpp_source.html +48 -40
  24. package/SVF-doxygen/html/html/SVFIR_8h_source.html +44 -40
  25. package/SVF-doxygen/html/html/SVFStatements_8cpp_source.html +21 -20
  26. package/SVF-doxygen/html/html/SVFStatements_8h.html +2 -0
  27. package/SVF-doxygen/html/html/SVFStatements_8h_source.html +107 -83
  28. package/SVF-doxygen/html/html/SaberSVFGBuilder_8cpp_source.html +1 -1
  29. package/SVF-doxygen/html/html/SymbolTableBuilder_8cpp_source.html +13 -13
  30. package/SVF-doxygen/html/html/SymbolTableBuilder_8h_source.html +12 -12
  31. package/SVF-doxygen/html/html/TypeBasedHeapCloning_8cpp_source.html +1 -1
  32. package/SVF-doxygen/html/html/VFGNode_8h_source.html +6 -6
  33. package/SVF-doxygen/html/html/VFG_8cpp_source.html +45 -43
  34. package/SVF-doxygen/html/html/VFG_8h_source.html +26 -26
  35. package/SVF-doxygen/html/html/annotated.html +58 -57
  36. package/SVF-doxygen/html/html/classSVF_1_1AddrCGEdge.html +2 -2
  37. package/SVF-doxygen/html/html/classSVF_1_1AddrStmt-members.html +14 -13
  38. package/SVF-doxygen/html/html/classSVF_1_1AddrStmt.html +4 -3
  39. package/SVF-doxygen/html/html/classSVF_1_1Andersen.html +1 -1
  40. package/SVF-doxygen/html/html/classSVF_1_1AndersenBase.html +3 -3
  41. package/SVF-doxygen/html/html/classSVF_1_1AndersenStat.html +1 -1
  42. package/SVF-doxygen/html/html/classSVF_1_1ArgumentVFGNode.html +2 -2
  43. package/SVF-doxygen/html/html/classSVF_1_1AssignStmt-members.html +14 -13
  44. package/SVF-doxygen/html/html/classSVF_1_1AssignStmt.html +4 -3
  45. package/SVF-doxygen/html/html/classSVF_1_1BVDataPTAImpl.html +3 -3
  46. package/SVF-doxygen/html/html/classSVF_1_1BinaryOPStmt-members.html +30 -28
  47. package/SVF-doxygen/html/html/classSVF_1_1BinaryOPStmt.html +26 -22
  48. package/SVF-doxygen/html/html/classSVF_1_1BinaryOPVFGNode.html +2 -2
  49. package/SVF-doxygen/html/html/classSVF_1_1BranchStmt-members.html +16 -15
  50. package/SVF-doxygen/html/html/classSVF_1_1BranchStmt.html +41 -40
  51. package/SVF-doxygen/html/html/classSVF_1_1BranchVFGNode.html +4 -4
  52. package/SVF-doxygen/html/html/classSVF_1_1CallPE-members.html +38 -35
  53. package/SVF-doxygen/html/html/classSVF_1_1CallPE.html +97 -32
  54. package/SVF-doxygen/html/html/classSVF_1_1CmpStmt-members.html +30 -28
  55. package/SVF-doxygen/html/html/classSVF_1_1CmpStmt.html +27 -23
  56. package/SVF-doxygen/html/html/classSVF_1_1CmpVFGNode.html +2 -2
  57. package/SVF-doxygen/html/html/classSVF_1_1CondPTAImpl.html +1 -1
  58. package/SVF-doxygen/html/html/classSVF_1_1ConstraintGraph.html +80 -78
  59. package/SVF-doxygen/html/html/classSVF_1_1ConstraintNode-members.html +26 -26
  60. package/SVF-doxygen/html/html/classSVF_1_1ConstraintNode.html +43 -43
  61. package/SVF-doxygen/html/html/classSVF_1_1CopyStmt-members.html +14 -13
  62. package/SVF-doxygen/html/html/classSVF_1_1CopyStmt.html +4 -3
  63. package/SVF-doxygen/html/html/classSVF_1_1DDAClient.html +2 -2
  64. package/SVF-doxygen/html/html/classSVF_1_1DDAPass.html +2 -2
  65. package/SVF-doxygen/html/html/classSVF_1_1DDAVFSolver.html +3 -3
  66. package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveStat.html +1 -1
  67. package/SVF-doxygen/html/html/classSVF_1_1GenericNode.html +20 -21
  68. package/SVF-doxygen/html/html/classSVF_1_1GenericNode.png +0 -0
  69. package/SVF-doxygen/html/html/classSVF_1_1GepStmt-members.html +15 -14
  70. package/SVF-doxygen/html/html/classSVF_1_1GepStmt.html +6 -5
  71. package/SVF-doxygen/html/html/classSVF_1_1LoadStmt-members.html +14 -13
  72. package/SVF-doxygen/html/html/classSVF_1_1LoadStmt.html +6 -5
  73. package/SVF-doxygen/html/html/classSVF_1_1MRGenerator.html +1 -1
  74. package/SVF-doxygen/html/html/classSVF_1_1MTAAnnotator.html +1 -1
  75. package/SVF-doxygen/html/html/classSVF_1_1MTASVFGBuilder.html +1 -1
  76. package/SVF-doxygen/html/html/classSVF_1_1MultiOpndStmt-members.html +33 -31
  77. package/SVF-doxygen/html/html/classSVF_1_1MultiOpndStmt.html +74 -32
  78. package/SVF-doxygen/html/html/classSVF_1_1MultiOpndStmt.png +0 -0
  79. package/SVF-doxygen/html/html/classSVF_1_1OfflineConsG.html +4 -4
  80. package/SVF-doxygen/html/html/classSVF_1_1PAGBuilderFromFile.html +9 -10
  81. package/SVF-doxygen/html/html/classSVF_1_1PHIVFGNode.html +2 -2
  82. package/SVF-doxygen/html/html/classSVF_1_1PhiStmt-members.html +21 -16
  83. package/SVF-doxygen/html/html/classSVF_1_1PhiStmt.html +186 -73
  84. package/SVF-doxygen/html/html/classSVF_1_1PointerAnalysis.html +2 -2
  85. package/SVF-doxygen/html/html/classSVF_1_1RetPE-members.html +37 -34
  86. package/SVF-doxygen/html/html/classSVF_1_1RetPE.html +99 -32
  87. package/SVF-doxygen/html/html/classSVF_1_1SVFG-members.html +1 -1
  88. package/SVF-doxygen/html/html/classSVF_1_1SVFG.html +10 -10
  89. package/SVF-doxygen/html/html/classSVF_1_1SVFGBuilder.html +1 -1
  90. package/SVF-doxygen/html/html/classSVF_1_1SVFGOPT-members.html +1 -1
  91. package/SVF-doxygen/html/html/classSVF_1_1SVFGOPT.html +8 -8
  92. package/SVF-doxygen/html/html/classSVF_1_1SVFIR-members.html +179 -178
  93. package/SVF-doxygen/html/html/classSVF_1_1SVFIR.html +208 -114
  94. package/SVF-doxygen/html/html/classSVF_1_1SVFIRBuilder-members.html +74 -73
  95. package/SVF-doxygen/html/html/classSVF_1_1SVFIRBuilder.html +288 -175
  96. package/SVF-doxygen/html/html/classSVF_1_1SVFStmt-members.html +17 -16
  97. package/SVF-doxygen/html/html/classSVF_1_1SVFStmt.html +9 -5
  98. package/SVF-doxygen/html/html/classSVF_1_1SVFStmt.png +0 -0
  99. package/SVF-doxygen/html/html/classSVF_1_1SaberSVFGBuilder.html +3 -3
  100. package/SVF-doxygen/html/html/classSVF_1_1SelectStmt-members.html +154 -0
  101. package/SVF-doxygen/html/html/classSVF_1_1SelectStmt.html +704 -0
  102. package/SVF-doxygen/html/html/classSVF_1_1SelectStmt.png +0 -0
  103. package/SVF-doxygen/html/html/classSVF_1_1StmtVFGNode.html +2 -2
  104. package/SVF-doxygen/html/html/classSVF_1_1StoreStmt-members.html +17 -16
  105. package/SVF-doxygen/html/html/classSVF_1_1StoreStmt.html +6 -5
  106. package/SVF-doxygen/html/html/classSVF_1_1SymbolTableBuilder.html +39 -39
  107. package/SVF-doxygen/html/html/classSVF_1_1TDForkPE-members.html +27 -25
  108. package/SVF-doxygen/html/html/classSVF_1_1TDForkPE.html +34 -24
  109. package/SVF-doxygen/html/html/classSVF_1_1TDJoinPE-members.html +27 -25
  110. package/SVF-doxygen/html/html/classSVF_1_1TDJoinPE.html +33 -24
  111. package/SVF-doxygen/html/html/classSVF_1_1TypeBasedHeapCloning.html +1 -1
  112. package/SVF-doxygen/html/html/classSVF_1_1UnaryOPStmt-members.html +17 -16
  113. package/SVF-doxygen/html/html/classSVF_1_1UnaryOPStmt.html +29 -28
  114. package/SVF-doxygen/html/html/classSVF_1_1VFG-members.html +1 -1
  115. package/SVF-doxygen/html/html/classSVF_1_1VFG.html +64 -62
  116. package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitiveStat.html +1 -1
  117. package/SVF-doxygen/html/html/classes.html +70 -70
  118. package/SVF-doxygen/html/html/functions_a.html +20 -16
  119. package/SVF-doxygen/html/html/functions_b.html +4 -2
  120. package/SVF-doxygen/html/html/functions_c.html +28 -20
  121. package/SVF-doxygen/html/html/functions_e.html +6 -2
  122. package/SVF-doxygen/html/html/functions_eval_s.html +3 -0
  123. package/SVF-doxygen/html/html/functions_f.html +3 -3
  124. package/SVF-doxygen/html/html/functions_func.html +20 -16
  125. package/SVF-doxygen/html/html/functions_func_c.html +19 -18
  126. package/SVF-doxygen/html/html/functions_func_g.html +23 -8
  127. package/SVF-doxygen/html/html/functions_func_o.html +2 -1
  128. package/SVF-doxygen/html/html/functions_func_r.html +1 -1
  129. package/SVF-doxygen/html/html/functions_func_s.html +8 -5
  130. package/SVF-doxygen/html/html/functions_func_t.html +1 -0
  131. package/SVF-doxygen/html/html/functions_g.html +24 -9
  132. package/SVF-doxygen/html/html/functions_i.html +8 -10
  133. package/SVF-doxygen/html/html/functions_l.html +5 -5
  134. package/SVF-doxygen/html/html/functions_m.html +1 -1
  135. package/SVF-doxygen/html/html/functions_n.html +3 -3
  136. package/SVF-doxygen/html/html/functions_o.html +17 -10
  137. package/SVF-doxygen/html/html/functions_p.html +6 -6
  138. package/SVF-doxygen/html/html/functions_s.html +21 -15
  139. package/SVF-doxygen/html/html/functions_t.html +9 -8
  140. package/SVF-doxygen/html/html/functions_type_o.html +3 -0
  141. package/SVF-doxygen/html/html/functions_v.html +3 -3
  142. package/SVF-doxygen/html/html/functions_vars_c.html +7 -0
  143. package/SVF-doxygen/html/html/functions_vars_e.html +4 -0
  144. package/SVF-doxygen/html/html/functions_vars_i.html +1 -3
  145. package/SVF-doxygen/html/html/functions_vars_o.html +3 -0
  146. package/SVF-doxygen/html/html/hierarchy.html +55 -54
  147. package/SVF-doxygen/html/html/namespaceSVF.html +3 -1
  148. package/SVF-doxygen/html/html/search/all_1.js +12 -11
  149. package/SVF-doxygen/html/html/search/all_10.js +6 -6
  150. package/SVF-doxygen/html/html/search/all_12.js +2 -2
  151. package/SVF-doxygen/html/html/search/all_13.js +10 -8
  152. package/SVF-doxygen/html/html/search/all_14.js +9 -9
  153. package/SVF-doxygen/html/html/search/all_15.js +1 -1
  154. package/SVF-doxygen/html/html/search/all_16.js +1 -1
  155. package/SVF-doxygen/html/html/search/all_2.js +1 -1
  156. package/SVF-doxygen/html/html/search/all_3.js +5 -5
  157. package/SVF-doxygen/html/html/search/all_5.js +2 -2
  158. package/SVF-doxygen/html/html/search/all_6.js +1 -1
  159. package/SVF-doxygen/html/html/search/all_7.js +7 -3
  160. package/SVF-doxygen/html/html/search/all_9.js +1 -1
  161. package/SVF-doxygen/html/html/search/all_c.js +2 -2
  162. package/SVF-doxygen/html/html/search/all_d.js +1 -1
  163. package/SVF-doxygen/html/html/search/all_e.js +6 -6
  164. package/SVF-doxygen/html/html/search/all_f.js +4 -2
  165. package/SVF-doxygen/html/html/search/classes_f.js +1 -0
  166. package/SVF-doxygen/html/html/search/enumvalues_f.js +1 -0
  167. package/SVF-doxygen/html/html/search/functions_0.js +12 -11
  168. package/SVF-doxygen/html/html/search/functions_10.js +2 -1
  169. package/SVF-doxygen/html/html/search/functions_11.js +3 -3
  170. package/SVF-doxygen/html/html/search/functions_2.js +2 -2
  171. package/SVF-doxygen/html/html/search/functions_6.js +7 -3
  172. package/SVF-doxygen/html/html/search/functions_d.js +1 -1
  173. package/SVF-doxygen/html/html/search/functions_e.js +1 -1
  174. package/SVF-doxygen/html/html/search/functions_f.js +1 -1
  175. package/SVF-doxygen/html/html/search/typedefs_e.js +1 -0
  176. package/SVF-doxygen/html/html/search/variables_14.js +4 -4
  177. package/SVF-doxygen/html/html/search/variables_15.js +1 -1
  178. package/SVF-doxygen/html/html/search/variables_3.js +2 -0
  179. package/SVF-doxygen/html/html/search/variables_5.js +2 -1
  180. package/SVF-doxygen/html/html/search/variables_9.js +1 -1
  181. package/SVF-doxygen/html/html/search/variables_e.js +4 -4
  182. package/SVF-doxygen/html/html/search/variables_f.js +1 -0
  183. package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01ConstraintGraph_01_5_01_4.html +16 -16
  184. package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01IRGraph_01_5_01_4.html +1 -1
  185. package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01VFG_01_5_01_4.html +18 -18
  186. package/include/Graphs/VFG.h +1 -1
  187. package/include/MemoryModel/SVFIR.h +7 -5
  188. package/include/MemoryModel/SVFStatements.h +100 -18
  189. package/include/SVF-FE/SVFIRBuilder.h +17 -10
  190. package/lib/Graphs/ConsG.cpp +9 -0
  191. package/lib/Graphs/VFG.cpp +9 -0
  192. package/lib/MemoryModel/PAGBuilderFromFile.cpp +5 -3
  193. package/lib/MemoryModel/SVFIR.cpp +32 -11
  194. package/lib/MemoryModel/SVFStatements.cpp +14 -0
  195. package/lib/SVF-FE/SVFIRBuilder.cpp +43 -22
  196. package/lib/SVF-FE/SymbolTableBuilder.cpp +1 -0
  197. package/package.json +1 -1
@@ -53,7 +53,7 @@ public:
53
53
  /// ThreadFork/ThreadJoin is to model parameter passings between thread spawners and spawnees.
54
54
  enum PEDGEK
55
55
  {
56
- Addr, Copy, Store, Load, Call, Ret, Gep, Phi, Cmp, BinaryOp, UnaryOp, Branch, ThreadFork, ThreadJoin
56
+ Addr, Copy, Store, Load, Call, Ret, Gep, Phi, Select, Cmp, BinaryOp, UnaryOp, Branch, ThreadFork, ThreadJoin
57
57
  };
58
58
 
59
59
  private:
@@ -481,7 +481,8 @@ private:
481
481
  CallPE(const CallPE &); ///< place holder
482
482
  void operator=(const CallPE &); ///< place holder
483
483
 
484
- const CallICFGNode* inst; ///< llvm instruction for this call
484
+ const CallICFGNode* call; /// the callsite statement calling from
485
+ const FunEntryICFGNode* entry; /// the function exit statement calling to
485
486
  public:
486
487
  /// Methods for support type inquiry through isa, cast, and dyn_cast:
487
488
  //@{
@@ -502,8 +503,8 @@ public:
502
503
  //@}
503
504
 
504
505
  /// constructor
505
- CallPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, GEdgeKind k = SVFStmt::Call) :
506
- AssignStmt(s,d,makeEdgeFlagWithCallInst(k,i)), inst(i)
506
+ CallPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunEntryICFGNode* e, GEdgeKind k = SVFStmt::Call) :
507
+ AssignStmt(s,d,makeEdgeFlagWithCallInst(k,i)), call(i), entry(e)
507
508
  {
508
509
  }
509
510
 
@@ -511,11 +512,15 @@ public:
511
512
  //@{
512
513
  inline const CallICFGNode* getCallInst() const
513
514
  {
514
- return inst;
515
+ return call;
515
516
  }
516
517
  inline const CallICFGNode* getCallSite() const
517
518
  {
518
- return inst;
519
+ return call;
520
+ }
521
+ inline const FunEntryICFGNode* getFunEntryICFGNode() const
522
+ {
523
+ return entry;
519
524
  }
520
525
  //@}
521
526
 
@@ -533,7 +538,8 @@ private:
533
538
  RetPE(const RetPE &); ///< place holder
534
539
  void operator=(const RetPE &); ///< place holder
535
540
 
536
- const CallICFGNode* inst; /// the callsite instruction return to
541
+ const CallICFGNode* call; /// the callsite statement returning to
542
+ const FunExitICFGNode* exit; /// the function exit statement returned from
537
543
  public:
538
544
  /// Methods for support type inquiry through isa, cast, and dyn_cast:
539
545
  //@{
@@ -554,8 +560,8 @@ public:
554
560
  //@}
555
561
 
556
562
  /// constructor
557
- RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, GEdgeKind k = SVFStmt::Ret) :
558
- AssignStmt(s,d,makeEdgeFlagWithCallInst(k,i)), inst(i)
563
+ RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e, GEdgeKind k = SVFStmt::Ret) :
564
+ AssignStmt(s,d,makeEdgeFlagWithCallInst(k,i)), call(i), exit(e)
559
565
  {
560
566
  }
561
567
 
@@ -563,11 +569,15 @@ public:
563
569
  //@{
564
570
  inline const CallICFGNode* getCallInst() const
565
571
  {
566
- return inst;
572
+ return call;
567
573
  }
568
574
  inline const CallICFGNode* getCallSite() const
569
575
  {
570
- return inst;
576
+ return call;
577
+ }
578
+ inline const FunExitICFGNode* getFunExitICFGNode() const
579
+ {
580
+ return exit;
571
581
  }
572
582
  //@}
573
583
 
@@ -605,12 +615,14 @@ public:
605
615
  static inline bool classof(const SVFStmt *node)
606
616
  {
607
617
  return node->getEdgeKind() == Phi ||
618
+ node->getEdgeKind() == Select ||
608
619
  node->getEdgeKind() == BinaryOp ||
609
620
  node->getEdgeKind() == Cmp;
610
621
  }
611
622
  static inline bool classof(const GenericPAGEdgeTy *node)
612
623
  {
613
624
  return node->getEdgeKind() == Phi ||
625
+ node->getEdgeKind() == Select ||
614
626
  node->getEdgeKind() == BinaryOp ||
615
627
  node->getEdgeKind() == Cmp;
616
628
  }
@@ -627,7 +639,16 @@ public:
627
639
  {
628
640
  return SVFStmt::getDstNode();
629
641
  }
630
-
642
+ /// Return the position of this op
643
+ const u32_t getOpPos(const SVFVar* op) const{
644
+ for(u32_t i = 0; i < getOpVarNum(); i++){
645
+ if(getOpVar(i)==op)
646
+ return i;
647
+ }
648
+ assert(false && "this operand not found!");
649
+ abort();
650
+ }
651
+
631
652
  NodeID getOpVarID(u32_t pos) const;
632
653
  NodeID getResID() const;
633
654
 
@@ -655,11 +676,15 @@ public:
655
676
  */
656
677
  class PhiStmt: public MultiOpndStmt
657
678
  {
679
+ public:
680
+ typedef std::vector<const ICFGNode* > OpICFGNodeVec;
681
+
658
682
  private:
659
683
  PhiStmt(); ///< place holder
660
684
  PhiStmt(const PhiStmt &); ///< place holder
661
685
  void operator=(const PhiStmt &); ///< place holder
662
686
 
687
+ OpICFGNodeVec opICFGNodes;
663
688
  public:
664
689
  /// Methods for support type inquiry through isa, cast, and dyn_cast:
665
690
  //@{
@@ -682,11 +707,19 @@ public:
682
707
  //@}
683
708
 
684
709
  /// constructor
685
- PhiStmt(SVFVar* s, const OPVars& opnds) : MultiOpndStmt(s,opnds,SVFStmt::Phi)
710
+ PhiStmt(SVFVar* s, const OPVars& opnds, const OpICFGNodeVec& icfgNodes) : MultiOpndStmt(s,opnds,SVFStmt::Phi), opICFGNodes(icfgNodes)
686
711
  {
712
+ assert(opnds.size()==icfgNodes.size() && "Numbers of operands and their ICFGNodes are not consistent?");
687
713
  }
688
- void addOpVar(SVFVar* op){
714
+ void addOpVar(SVFVar* op, const ICFGNode* inode){
689
715
  opVars.push_back(op);
716
+ opICFGNodes.push_back(inode);
717
+ assert(opVars.size()==opICFGNodes.size() && "Numbers of operands and their ICFGNodes are not consistent?");
718
+ }
719
+
720
+ /// Return the corresponding ICFGNode of this operand
721
+ inline const ICFGNode* getOpICFGNode(const SVFVar* op) const{
722
+ return opICFGNodes.at(getOpPos(op));
690
723
  }
691
724
 
692
725
  /// Return true if this is a phi at the function exit
@@ -696,6 +729,55 @@ public:
696
729
  virtual const std::string toString() const override;
697
730
  };
698
731
 
732
+ /*!
733
+ * Select statement (e.g., p ? q: r which receives values from variables q and r based on condition p)
734
+ */
735
+ class SelectStmt: public MultiOpndStmt
736
+ {
737
+ private:
738
+ SelectStmt(); ///< place holder
739
+ SelectStmt(const SelectStmt &); ///< place holder
740
+ void operator=(const SelectStmt &); ///< place holder
741
+
742
+ const SVFVar* condition;
743
+ public:
744
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
745
+ //@{
746
+ static inline bool classof(const SelectStmt *)
747
+ {
748
+ return true;
749
+ }
750
+ static inline bool classof(const SVFStmt *edge)
751
+ {
752
+ return edge->getEdgeKind() == SVFStmt::Select;
753
+ }
754
+ static inline bool classof(const MultiOpndStmt *edge)
755
+ {
756
+ return edge->getEdgeKind() == SVFStmt::Select;
757
+ }
758
+ static inline bool classof(const GenericPAGEdgeTy *edge)
759
+ {
760
+ return edge->getEdgeKind() == SVFStmt::Select;
761
+ }
762
+ //@}
763
+
764
+ /// constructor
765
+ SelectStmt(SVFVar* s, const OPVars& opnds, const SVFVar* cond) : MultiOpndStmt(s,opnds,SVFStmt::Select), condition(cond)
766
+ {
767
+ assert(opnds.size()==2 && "SelectStmt can only have two operands!");
768
+ }
769
+ virtual const std::string toString() const override;
770
+
771
+ inline const SVFVar* getCondition() const{
772
+ return condition;
773
+ }
774
+ inline const SVFVar* getTrueValue() const{
775
+ return getOpVar(0);
776
+ }
777
+ inline const SVFVar* getFalseValue() const{
778
+ return getOpVar(1);
779
+ }
780
+ };
699
781
 
700
782
  /*!
701
783
  * Comparison statement
@@ -950,8 +1032,8 @@ public:
950
1032
  //@}
951
1033
 
952
1034
  /// constructor
953
- TDForkPE(SVFVar* s, SVFVar* d, const CallICFGNode* i) :
954
- CallPE(s,d,i,SVFStmt::ThreadFork)
1035
+ TDForkPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunEntryICFGNode* entry) :
1036
+ CallPE(s,d,i,entry,SVFStmt::ThreadFork)
955
1037
  {
956
1038
  }
957
1039
 
@@ -988,8 +1070,8 @@ public:
988
1070
  //@}
989
1071
 
990
1072
  /// Constructor
991
- TDJoinPE(SVFVar* s, SVFVar* d, const CallICFGNode* i) :
992
- RetPE(s,d,i,SVFStmt::ThreadJoin)
1073
+ TDJoinPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e) :
1074
+ RetPE(s,d,i,e, SVFStmt::ThreadJoin)
993
1075
  {
994
1076
  }
995
1077
 
@@ -306,9 +306,16 @@ public:
306
306
  return edge;
307
307
  }
308
308
  /// Add Copy edge
309
- inline PhiStmt* addPhiStmt(NodeID res, NodeID opnd)
309
+ inline PhiStmt* addPhiStmt(NodeID res, NodeID opnd, const ICFGNode* pred)
310
310
  {
311
- PhiStmt *edge = pag->addPhiStmt(res,opnd);
311
+ PhiStmt *edge = pag->addPhiStmt(res,opnd,pred);
312
+ setCurrentBBAndValueForPAGEdge(edge);
313
+ return edge;
314
+ }
315
+ /// Add SelectStmt
316
+ inline SelectStmt* addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond)
317
+ {
318
+ SelectStmt *edge = pag->addSelectStmt(res,op1,op2,cond);
312
319
  setCurrentBBAndValueForPAGEdge(edge);
313
320
  return edge;
314
321
  }
@@ -359,16 +366,16 @@ public:
359
366
  return edge;
360
367
  }
361
368
  /// Add Call edge
362
- inline CallPE* addCallEdge(NodeID src, NodeID dst, const CallICFGNode* cs)
369
+ inline CallPE* addCallEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry)
363
370
  {
364
- CallPE *edge = pag->addCallPE(src, dst, cs);
371
+ CallPE *edge = pag->addCallPE(src, dst, cs, entry);
365
372
  setCurrentBBAndValueForPAGEdge(edge);
366
373
  return edge;
367
374
  }
368
375
  /// Add Return edge
369
- inline RetPE* addRetEdge(NodeID src, NodeID dst, const CallICFGNode* cs)
376
+ inline RetPE* addRetEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit)
370
377
  {
371
- RetPE *edge = pag->addRetPE(src, dst, cs);
378
+ RetPE *edge = pag->addRetPE(src, dst, cs, exit);
372
379
  setCurrentBBAndValueForPAGEdge(edge);
373
380
  return edge;
374
381
  }
@@ -394,16 +401,16 @@ public:
394
401
  return edge;
395
402
  }
396
403
  /// Add Thread fork edge for parameter passing
397
- inline TDForkPE* addThreadForkEdge(NodeID src, NodeID dst, const CallICFGNode* cs)
404
+ inline TDForkPE* addThreadForkEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry)
398
405
  {
399
- TDForkPE *edge = pag->addThreadForkPE(src, dst, cs);
406
+ TDForkPE *edge = pag->addThreadForkPE(src, dst, cs, entry);
400
407
  setCurrentBBAndValueForPAGEdge(edge);
401
408
  return edge;
402
409
  }
403
410
  /// Add Thread join edge for parameter passing
404
- inline TDJoinPE* addThreadJoinEdge(NodeID src, NodeID dst, const CallICFGNode* cs)
411
+ inline TDJoinPE* addThreadJoinEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit)
405
412
  {
406
- TDJoinPE *edge = pag->addThreadJoinPE(src, dst, cs);
413
+ TDJoinPE *edge = pag->addThreadJoinPE(src, dst, cs, exit);
407
414
  setCurrentBBAndValueForPAGEdge(edge);
408
415
  return edge;
409
416
  }
@@ -74,6 +74,15 @@ void ConstraintGraph::buildCG()
74
74
  addCopyCGEdge(opVar->getId(),edge->getResID());
75
75
  }
76
76
 
77
+ SVFStmt::SVFStmtSetTy& selects = getPAGEdgeSet(SVFStmt::Select);
78
+ for (SVFStmt::SVFStmtSetTy::iterator iter = selects.begin(), eiter =
79
+ selects.end(); iter != eiter; ++iter)
80
+ {
81
+ const SelectStmt* edge = SVFUtil::cast<SelectStmt>(*iter);
82
+ for(const auto opVar : edge->getOpndVars())
83
+ addCopyCGEdge(opVar->getId(),edge->getResID());
84
+ }
85
+
77
86
  SVFStmt::SVFStmtSetTy& calls = getPAGEdgeSet(SVFStmt::Call);
78
87
  for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter =
79
88
  calls.end(); iter != eiter; ++iter)
@@ -489,6 +489,15 @@ void VFG::addVFGNodes()
489
489
  if(isInterestedPAGNode(edge->getRes()))
490
490
  addIntraPHIVFGNode(edge);
491
491
  }
492
+ // initialize select statement
493
+ SVFStmt::SVFStmtSetTy& selects = getPAGEdgeSet(SVFStmt::Select);
494
+ for (SVFStmt::SVFStmtSetTy::iterator iter = selects.begin(), eiter =
495
+ selects.end(); iter != eiter; ++iter)
496
+ {
497
+ const MultiOpndStmt* edge = SVFUtil::cast<MultiOpndStmt>(*iter);
498
+ if(isInterestedPAGNode(edge->getRes()))
499
+ addIntraPHIVFGNode(edge);
500
+ }
492
501
  // initialize llvm binary nodes (binary operators)
493
502
  SVFStmt::SVFStmtSetTy& binaryops = getPAGEdgeSet(SVFStmt::BinaryOp);
494
503
  for (SVFStmt::SVFStmtSetTy::iterator iter = binaryops.begin(), eiter =
@@ -173,9 +173,9 @@ void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID,
173
173
  else if (edge == "variant-gep")
174
174
  pag->addVariantGepStmt(srcID, dstID, LocationSet(offsetOrCSId));
175
175
  else if (edge == "call")
176
- pag->addEdge(srcNode, dstNode, new CallPE(srcNode, dstNode, nullptr));
176
+ pag->addEdge(srcNode, dstNode, new CallPE(srcNode, dstNode, nullptr, nullptr));
177
177
  else if (edge == "ret")
178
- pag->addEdge(srcNode, dstNode, new RetPE(srcNode, dstNode, nullptr));
178
+ pag->addEdge(srcNode, dstNode, new RetPE(srcNode, dstNode, nullptr,nullptr));
179
179
  else if (edge == "cmp")
180
180
  pag->addCmpStmt(srcID, dstID, dstID, dstID);
181
181
  else if (edge == "binary-op")
@@ -183,7 +183,9 @@ void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID,
183
183
  else if (edge == "unary-op")
184
184
  pag->addUnaryOPStmt(srcID, dstID, dstID);
185
185
  else if (edge == "phi")
186
- pag->addPhiStmt(srcID, dstID);
186
+ assert(false && "fix phi here!");
187
+ else if (edge == "select")
188
+ assert(false && "fix select here!");
187
189
  else if (edge == "branch"){
188
190
  assert(false && "fix successors here!");
189
191
  //pag->addBranchStmt(srcID, dstID, nullptr);
@@ -84,24 +84,45 @@ CopyStmt* SVFIR::addCopyStmt(NodeID src, NodeID dst)
84
84
  /*!
85
85
  * Add Phi statement
86
86
  */
87
- PhiStmt* SVFIR::addPhiStmt(NodeID res, NodeID opnd)
87
+ PhiStmt* SVFIR::addPhiStmt(NodeID res, NodeID opnd, const ICFGNode* pred)
88
88
  {
89
89
  SVFVar* opNode = getGNode(opnd);
90
90
  SVFVar* resNode = getGNode(res);
91
91
  PHINodeMap::iterator it = phiNodeMap.find(resNode);
92
92
  if(it == phiNodeMap.end()){
93
- PhiStmt* phi = new PhiStmt(resNode, {opNode});
93
+ PhiStmt* phi = new PhiStmt(resNode, {opNode}, {pred});
94
94
  addToStmt2TypeMap(phi);
95
95
  addEdge(opNode, resNode, phi);
96
96
  phiNodeMap[resNode] = phi;
97
97
  return phi;
98
98
  }
99
99
  else{
100
- it->second->addOpVar(opNode);
100
+ it->second->addOpVar(opNode,pred);
101
101
  return it->second;
102
102
  }
103
103
  }
104
104
 
105
+ /*!
106
+ * Add Phi statement
107
+ */
108
+ SelectStmt* SVFIR::addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond)
109
+ {
110
+ SVFVar* op1Node = getGNode(op1);
111
+ SVFVar* op2Node = getGNode(op2);
112
+ SVFVar* dstNode = getGNode(res);
113
+ SVFVar* condNode = getGNode(cond);
114
+ if(SVFStmt* edge = hasLabeledEdge(op1Node, dstNode, SVFStmt::Select, op2Node))
115
+ return SVFUtil::cast<SelectStmt>(edge);
116
+ else
117
+ {
118
+ std::vector<SVFVar*> opnds = {op1Node, op2Node};
119
+ SelectStmt* select = new SelectStmt(dstNode, opnds, condNode);
120
+ addToStmt2TypeMap(select);
121
+ addEdge(op1Node, dstNode, select);
122
+ return select;
123
+ }
124
+ }
125
+
105
126
  /*!
106
127
  * Add Compare edge
107
128
  */
@@ -219,7 +240,7 @@ StoreStmt* SVFIR::addStoreStmt(NodeID src, NodeID dst, const IntraICFGNode* curV
219
240
  /*!
220
241
  * Add Call edge
221
242
  */
222
- CallPE* SVFIR::addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs)
243
+ CallPE* SVFIR::addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry)
223
244
  {
224
245
  SVFVar* srcNode = getGNode(src);
225
246
  SVFVar* dstNode = getGNode(dst);
@@ -227,7 +248,7 @@ CallPE* SVFIR::addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs)
227
248
  return SVFUtil::cast<CallPE>(edge);
228
249
  else
229
250
  {
230
- CallPE* callPE = new CallPE(srcNode, dstNode, cs);
251
+ CallPE* callPE = new CallPE(srcNode, dstNode, cs,entry);
231
252
  addToStmt2TypeMap(callPE);
232
253
  addEdge(srcNode,dstNode, callPE);
233
254
  return callPE;
@@ -237,7 +258,7 @@ CallPE* SVFIR::addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs)
237
258
  /*!
238
259
  * Add Return edge
239
260
  */
240
- RetPE* SVFIR::addRetPE(NodeID src, NodeID dst, const CallICFGNode* cs)
261
+ RetPE* SVFIR::addRetPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit)
241
262
  {
242
263
  SVFVar* srcNode = getGNode(src);
243
264
  SVFVar* dstNode = getGNode(dst);
@@ -245,7 +266,7 @@ RetPE* SVFIR::addRetPE(NodeID src, NodeID dst, const CallICFGNode* cs)
245
266
  return SVFUtil::cast<RetPE>(edge);
246
267
  else
247
268
  {
248
- RetPE* retPE = new RetPE(srcNode, dstNode, cs);
269
+ RetPE* retPE = new RetPE(srcNode, dstNode, cs, exit);
249
270
  addToStmt2TypeMap(retPE);
250
271
  addEdge(srcNode,dstNode, retPE);
251
272
  return retPE;
@@ -266,7 +287,7 @@ SVFStmt* SVFIR::addBlackHoleAddrStmt(NodeID node)
266
287
  /*!
267
288
  * Add Thread fork edge for parameter passing from a spawner to its spawnees
268
289
  */
269
- TDForkPE* SVFIR::addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode* cs)
290
+ TDForkPE* SVFIR::addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry)
270
291
  {
271
292
  SVFVar* srcNode = getGNode(src);
272
293
  SVFVar* dstNode = getGNode(dst);
@@ -274,7 +295,7 @@ TDForkPE* SVFIR::addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode* cs)
274
295
  return SVFUtil::cast<TDForkPE>(edge);
275
296
  else
276
297
  {
277
- TDForkPE* forkPE = new TDForkPE(srcNode, dstNode, cs);
298
+ TDForkPE* forkPE = new TDForkPE(srcNode, dstNode, cs, entry);
278
299
  addToStmt2TypeMap(forkPE);
279
300
  addEdge(srcNode,dstNode, forkPE);
280
301
  return forkPE;
@@ -284,7 +305,7 @@ TDForkPE* SVFIR::addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode* cs)
284
305
  /*!
285
306
  * Add Thread fork edge for parameter passing from a spawnee back to its spawners
286
307
  */
287
- TDJoinPE* SVFIR::addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode* cs)
308
+ TDJoinPE* SVFIR::addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit)
288
309
  {
289
310
  SVFVar* srcNode = getGNode(src);
290
311
  SVFVar* dstNode = getGNode(dst);
@@ -292,7 +313,7 @@ TDJoinPE* SVFIR::addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode* cs)
292
313
  return SVFUtil::cast<TDJoinPE>(edge);
293
314
  else
294
315
  {
295
- TDJoinPE* joinPE = new TDJoinPE(srcNode, dstNode, cs);
316
+ TDJoinPE* joinPE = new TDJoinPE(srcNode, dstNode, cs, exit);
296
317
  addToStmt2TypeMap(joinPE);
297
318
  addEdge(srcNode,dstNode, joinPE);
298
319
  return joinPE;
@@ -101,6 +101,20 @@ const std::string PhiStmt::toString() const{
101
101
  return rawstr.str();
102
102
  }
103
103
 
104
+ const std::string SelectStmt::toString() const{
105
+ std::string str;
106
+ raw_string_ostream rawstr(str);
107
+ rawstr << "SelectStmt: (Condition Var" << getCondition()->getId() << ") [Var" << getResID() << " <-- (Var";
108
+ for(const SVFVar* op : getOpndVars())
109
+ rawstr << op->getId() << ",";
110
+ rawstr << ")]\t";
111
+ if (Options::ShowSVFIRValue) {
112
+ rawstr << "\n";
113
+ rawstr << value2String(getValue());
114
+ }
115
+ return rawstr.str();
116
+ }
117
+
104
118
  const std::string CmpStmt::toString() const{
105
119
  std::string str;
106
120
  raw_string_ostream rawstr(str);
@@ -369,11 +369,11 @@ void SVFIRBuilder::processCE(const Value *val)
369
369
  const Value* cval = getCurrentValue();
370
370
  const BasicBlock* cbb = getCurrentBB();
371
371
  setCurrentLocation(selectce, nullptr);
372
+ NodeID cond = pag->getValueNode(selectce->getOperand(0));
372
373
  NodeID nsrc1 = pag->getValueNode(src1);
373
374
  NodeID nsrc2 = pag->getValueNode(src2);
374
375
  NodeID nres = pag->getValueNode(selectce);
375
- addPhiStmt(nres,nsrc1);
376
- addPhiStmt(nres,nsrc2);
376
+ addSelectStmt(nres,nsrc1, nsrc2, cond);
377
377
  setCurrentLocation(cval, cbb);
378
378
  }
379
379
  // if we meet a int2ptr, then it points-to black hole
@@ -629,9 +629,10 @@ void SVFIRBuilder::visitPHINode(PHINode &inst)
629
629
  const Value* val = inst.getIncomingValue(i);
630
630
  const Instruction* incomingInst = SVFUtil::dyn_cast<Instruction>(val);
631
631
  assert((incomingInst==nullptr) || (incomingInst->getFunction() == inst.getFunction()));
632
-
632
+ const Instruction* predInst = &inst.getIncomingBlock(i)->front();
633
+ const ICFGNode* icfgNode = pag->getICFG()->getICFGNode(predInst);
633
634
  NodeID src = getValueNode(val);
634
- addPhiStmt(dst,src);
635
+ addPhiStmt(dst,src,icfgNode);
635
636
  }
636
637
  }
637
638
 
@@ -772,10 +773,9 @@ void SVFIRBuilder::visitSelectInst(SelectInst &inst)
772
773
  NodeID dst = getValueNode(&inst);
773
774
  NodeID src1 = getValueNode(inst.getTrueValue());
774
775
  NodeID src2 = getValueNode(inst.getFalseValue());
775
-
776
+ NodeID cond = getValueNode(inst.getCondition());
776
777
  /// Two operands have same incoming basic block, both are the current BB
777
- addPhiStmt(dst,src1);
778
- addPhiStmt(dst,src2);
778
+ addSelectStmt(dst,src1,src2, cond);
779
779
  }
780
780
 
781
781
  /*
@@ -841,8 +841,9 @@ void SVFIRBuilder::visitReturnInst(ReturnInst &inst)
841
841
 
842
842
  NodeID rnF = getReturnNode(F);
843
843
  NodeID vnS = getValueNode(src);
844
+ const ICFGNode* icfgNode = pag->getICFG()->getICFGNode(&inst);
844
845
  //vnS may be null if src is a null ptr
845
- addPhiStmt(rnF,vnS);
846
+ addPhiStmt(rnF,vnS,icfgNode);
846
847
  }
847
848
  }
848
849
 
@@ -892,7 +893,7 @@ void SVFIRBuilder::visitBranchInst(BranchInst &inst){
892
893
  BranchStmt::SuccAndCondPairVec successors;
893
894
  for (u32_t i = 0; i < inst.getNumSuccessors(); ++i)
894
895
  {
895
- const Instruction* succInst = &inst.getSuccessor(i)->front();
896
+ const Instruction* succInst = &inst.getSuccessor(i)->back();
896
897
  const ICFGNode* icfgNode = pag->getICFG()->getICFGNode(succInst);
897
898
  successors.push_back(std::make_pair(icfgNode, 1-i));
898
899
  }
@@ -960,8 +961,9 @@ void SVFIRBuilder::handleDirectCall(CallSite cs, const SVFFunction *F)
960
961
  if (!cs.getType()->isVoidTy())
961
962
  {
962
963
  NodeID srcret = getReturnNode(F);
963
- CallICFGNode* icfgNode = pag->getICFG()->getCallICFGNode(cs.getInstruction());
964
- addRetEdge(srcret, dstrec,icfgNode);
964
+ CallICFGNode* callICFGNode = pag->getICFG()->getCallICFGNode(cs.getInstruction());
965
+ FunExitICFGNode* exitICFGNode = pag->getICFG()->getFunExitICFGNode(F);
966
+ addRetEdge(srcret, dstrec,callICFGNode, exitICFGNode);
965
967
  }
966
968
  //Iterators for the actual and formal parameters
967
969
  CallSite::arg_iterator itA = cs.arg_begin(), ieA = cs.arg_end();
@@ -983,7 +985,8 @@ void SVFIRBuilder::handleDirectCall(CallSite cs, const SVFFunction *F)
983
985
  NodeID dstFA = getValueNode(FA);
984
986
  NodeID srcAA = getValueNode(AA);
985
987
  CallICFGNode* icfgNode = pag->getICFG()->getCallICFGNode(cs.getInstruction());
986
- addCallEdge(srcAA, dstFA, icfgNode);
988
+ FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(F);
989
+ addCallEdge(srcAA, dstFA, icfgNode, entry);
987
990
  }
988
991
  //Any remaining actual args must be varargs.
989
992
  if (F->getLLVMFun()->isVarArg())
@@ -995,7 +998,8 @@ void SVFIRBuilder::handleDirectCall(CallSite cs, const SVFFunction *F)
995
998
  Value *AA = *itA;
996
999
  NodeID vnAA = getValueNode(AA);
997
1000
  CallICFGNode* icfgNode = pag->getICFG()->getCallICFGNode(cs.getInstruction());
998
- addCallEdge(vnAA,vaF, icfgNode);
1001
+ FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(F);
1002
+ addCallEdge(vnAA,vaF, icfgNode,entry);
999
1003
  }
1000
1004
  }
1001
1005
  if(itA != ieA)
@@ -1478,7 +1482,8 @@ void SVFIRBuilder::handleExtCall(CallSite cs, const SVFFunction *callee)
1478
1482
  if(SVFUtil::isa<PointerType>(actualParm->getType()) && SVFUtil::isa<PointerType>(formalParm->getType()) )
1479
1483
  {
1480
1484
  CallICFGNode* icfgNode = pag->getICFG()->getCallICFGNode(inst);
1481
- addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm),icfgNode);
1485
+ FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(forkedFun));
1486
+ addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm),icfgNode, entry);
1482
1487
  }
1483
1488
  }
1484
1489
  }
@@ -1507,7 +1512,8 @@ void SVFIRBuilder::handleExtCall(CallSite cs, const SVFFunction *callee)
1507
1512
  if(SVFUtil::isa<PointerType>(actualParm->getType()) && SVFUtil::isa<PointerType>(formalParm->getType()) )
1508
1513
  {
1509
1514
  CallICFGNode* icfgNode = pag->getICFG()->getCallICFGNode(inst);
1510
- addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm),icfgNode);
1515
+ FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(taskFunc));
1516
+ addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm),icfgNode, entry);
1511
1517
  }
1512
1518
  }
1513
1519
  else
@@ -1635,12 +1641,16 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge)
1635
1641
  assert(curBB && "instruction does not have a basic block??");
1636
1642
 
1637
1643
  /// We will have one unique function exit ICFGNode for all returns
1638
- if(const ReturnInst* retInst = SVFUtil::dyn_cast<ReturnInst>(curVal)){
1644
+ if(const ReturnInst* retInst = SVFUtil::dyn_cast<ReturnInst>(curInst)){
1639
1645
  const SVFFunction *fun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(retInst->getParent()->getParent());
1640
1646
  icfgNode = pag->getICFG()->getFunExitICFGNode(fun);
1641
1647
  }
1642
- else
1643
- icfgNode = pag->getICFG()->getICFGNode(curInst);
1648
+ else{
1649
+ if(SVFUtil::isa<RetPE>(edge))
1650
+ icfgNode = pag->getICFG()->getRetICFGNode(curInst);
1651
+ else
1652
+ icfgNode = pag->getICFG()->getICFGNode(curInst);
1653
+ }
1644
1654
  }
1645
1655
  else if (const Argument* arg = SVFUtil::dyn_cast<Argument>(curVal))
1646
1656
  {
@@ -1656,12 +1666,20 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge)
1656
1666
  icfgNode = pag->getICFG()->getICFGNode(&curBB->front());
1657
1667
  }
1658
1668
  else if (SVFUtil::isa<GlobalVariable>(curVal) ||
1659
- SVFUtil::isa<Function>(curVal) ||
1660
1669
  SVFUtil::isa<Constant>(curVal) ||
1661
1670
  SVFUtil::isa<MetadataAsValue>(curVal))
1662
1671
  {
1663
1672
  pag->addGlobalPAGEdge(edge);
1664
1673
  }
1674
+ else if(const Function* fun = SVFUtil::dyn_cast<Function>(curVal)){
1675
+ const SVFFunction* f = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun);
1676
+ if((&fun->getEntryBlock() == curBB) && isExtCall(f)){
1677
+ /// all external function connected to a indirect call, we will put SVFStmts in the FunctionEntryICFGNode
1678
+ icfgNode = pag->getICFG()->getFunEntryICFGNode(f);
1679
+ }
1680
+ else
1681
+ pag->addGlobalPAGEdge(edge);
1682
+ }
1665
1683
  else
1666
1684
  {
1667
1685
  assert(false && "what else value can we have?");
@@ -1702,16 +1720,19 @@ void SVFIRBuilder::updateCallGraph(PTACallGraph* callgraph){
1702
1720
  {
1703
1721
  const CallICFGNode* callBlock = iter->first;
1704
1722
  CallSite cs = getLLVMCallSite(callBlock->getCallSite());
1705
- setCurrentLocation(callBlock->getCallSite(), callBlock->getCallSite()->getParent());
1706
1723
  assert(callBlock->isIndirectCall() && "this is not an indirect call?");
1707
1724
  const PTACallGraph::FunctionSet & functions = iter->second;
1708
1725
  for (PTACallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
1709
1726
  {
1710
1727
  const SVFFunction* callee = *func_iter;
1711
- if (isExtCall(callee))
1728
+ if (isExtCall(callee)){
1729
+ setCurrentLocation(callee->getLLVMFun(), &callee->getLLVMFun()->getEntryBlock());
1712
1730
  handleExtCall(cs, callee);
1713
- else
1731
+ }
1732
+ else{
1733
+ setCurrentLocation(callBlock->getCallSite(), callBlock->getCallSite()->getParent());
1714
1734
  handleDirectCall(cs, callee);
1735
+ }
1715
1736
  }
1716
1737
  }
1717
1738
 
@@ -130,6 +130,7 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule)
130
130
  {
131
131
  collectSym(sel->getTrueValue());
132
132
  collectSym(sel->getFalseValue());
133
+ collectSym(sel->getCondition());
133
134
  }
134
135
  else if (const BinaryOperator *binary = SVFUtil::dyn_cast<BinaryOperator>(inst))
135
136
  {