svf-tools 1.0.1231 → 1.0.1233
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/svf/include/Graphs/VFG.h +2 -4
- package/svf/include/Graphs/VFGNode.h +8 -13
- package/svf/include/SVFIR/SVFIR.h +9 -1
- package/svf/include/SVFIR/SVFStatements.h +83 -75
- package/svf/include/SVFIR/SVFVariables.h +48 -12
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +15 -3
- package/svf/lib/Graphs/ConsG.cpp +6 -4
- package/svf/lib/Graphs/ICFG.cpp +1 -11
- package/svf/lib/Graphs/IRGraph.cpp +1 -1
- package/svf/lib/Graphs/VFG.cpp +26 -33
- package/svf/lib/SVFIR/PAGBuilderFromFile.cpp +1 -1
- package/svf/lib/SVFIR/SVFIR.cpp +30 -16
- package/svf/lib/SVFIR/SVFStatements.cpp +25 -37
- package/svf-llvm/lib/SVFIRBuilder.cpp +18 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1233",
|
|
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": {
|
package/svf/include/Graphs/VFG.h
CHANGED
|
@@ -597,13 +597,11 @@ protected:
|
|
|
597
597
|
/// do not set def here, this node is not a variable definition
|
|
598
598
|
}
|
|
599
599
|
/// Add a formal parameter VFG node
|
|
600
|
-
inline void addFormalParmVFGNode(const ValVar* fparm, const FunObjVar* fun,
|
|
600
|
+
inline void addFormalParmVFGNode(const ValVar* fparm, const FunObjVar* fun, const CallPE* callPE)
|
|
601
601
|
{
|
|
602
602
|
FormalParmVFGNode* sNode = new FormalParmVFGNode(totalVFGNode++,fparm,fun);
|
|
603
603
|
addVFGNode(sNode, pag->getICFG()->getFunEntryICFGNode(fun));
|
|
604
|
-
|
|
605
|
-
it!=eit; ++it)
|
|
606
|
-
sNode->addCallPE(*it);
|
|
604
|
+
sNode->setCallPE(callPE);
|
|
607
605
|
|
|
608
606
|
setDef(fparm,sNode);
|
|
609
607
|
SVFVarToFormalParmMap[fparm] = sNode;
|
|
@@ -1028,12 +1028,12 @@ class FormalParmVFGNode : public ArgumentVFGNode
|
|
|
1028
1028
|
{
|
|
1029
1029
|
private:
|
|
1030
1030
|
const FunObjVar* fun;
|
|
1031
|
-
|
|
1031
|
+
const CallPE* callPE;
|
|
1032
1032
|
|
|
1033
1033
|
public:
|
|
1034
1034
|
/// Constructor
|
|
1035
1035
|
FormalParmVFGNode(NodeID id, const ValVar* n, const FunObjVar* f):
|
|
1036
|
-
ArgumentVFGNode(id, n, FParm), fun(f)
|
|
1036
|
+
ArgumentVFGNode(id, n, FParm), fun(f), callPE(nullptr)
|
|
1037
1037
|
{
|
|
1038
1038
|
}
|
|
1039
1039
|
|
|
@@ -1048,20 +1048,15 @@ public:
|
|
|
1048
1048
|
{
|
|
1049
1049
|
return fun;
|
|
1050
1050
|
}
|
|
1051
|
-
///
|
|
1052
|
-
inline void
|
|
1051
|
+
/// Set the (single, phi-like) CallPE for this formal parameter
|
|
1052
|
+
inline void setCallPE(const CallPE* call)
|
|
1053
1053
|
{
|
|
1054
|
-
|
|
1054
|
+
callPE = call;
|
|
1055
1055
|
}
|
|
1056
|
-
///
|
|
1057
|
-
|
|
1058
|
-
inline CallPESet::const_iterator callPEBegin() const
|
|
1059
|
-
{
|
|
1060
|
-
return callPEs.begin();
|
|
1061
|
-
}
|
|
1062
|
-
inline CallPESet::const_iterator callPEEnd() const
|
|
1056
|
+
/// Return the CallPE (phi-like, merges all actual params)
|
|
1057
|
+
inline const CallPE* getCallPE() const
|
|
1063
1058
|
{
|
|
1064
|
-
return
|
|
1059
|
+
return callPE;
|
|
1065
1060
|
}
|
|
1066
1061
|
//@}
|
|
1067
1062
|
|
|
@@ -57,6 +57,7 @@ public:
|
|
|
57
57
|
typedef std::vector<const SVFStmt*> SVFStmtList;
|
|
58
58
|
typedef std::vector<const ValVar*> ValVarList;
|
|
59
59
|
typedef Map<const SVFVar*,PhiStmt*> PHINodeMap;
|
|
60
|
+
typedef Map<const SVFVar*,CallPE*> FParmToCallPEMap;
|
|
60
61
|
typedef Map<const FunObjVar*,ValVarList> FunToArgsListMap;
|
|
61
62
|
typedef Map<const CallICFGNode*,ValVarList> CSToArgsListMap;
|
|
62
63
|
typedef Map<const RetICFGNode*,const ValVar*> CSToRetMap;
|
|
@@ -84,6 +85,7 @@ private:
|
|
|
84
85
|
MemObjToFieldsMap memToFieldsMap; ///< Map a mem object id to all its fields
|
|
85
86
|
SVFStmtSet globSVFStmtSet; ///< Global PAGEdges without control flow information
|
|
86
87
|
PHINodeMap phiNodeMap; ///< A set of phi copy edges
|
|
88
|
+
FParmToCallPEMap fParmToCallPEMap; ///< Map a formal param to its CallPE
|
|
87
89
|
FunToArgsListMap funArgsListMap; ///< Map a function to a list of all its formal parameters
|
|
88
90
|
CSToArgsListMap callSiteArgsListMap; ///< Map a callsite to a list of all its actual parameters
|
|
89
91
|
CSToRetMap callSiteRetMap; ///< Map a callsite to its callsite returns PAGNodes
|
|
@@ -353,6 +355,12 @@ public:
|
|
|
353
355
|
{
|
|
354
356
|
return phiNodeMap.find(node) != phiNodeMap.end();
|
|
355
357
|
}
|
|
358
|
+
/// Get the CallPE for a formal parameter (phi-like, nullptr if not found)
|
|
359
|
+
inline CallPE* getCallPEForFormalParm(const SVFVar* param) const
|
|
360
|
+
{
|
|
361
|
+
auto it = fParmToCallPEMap.find(param);
|
|
362
|
+
return it != fParmToCallPEMap.end() ? it->second : nullptr;
|
|
363
|
+
}
|
|
356
364
|
|
|
357
365
|
/// Function has arguments list
|
|
358
366
|
inline bool hasFunArgsList(const FunObjVar* func) const
|
|
@@ -911,7 +919,7 @@ private:
|
|
|
911
919
|
/// Add Store edge
|
|
912
920
|
StoreStmt* addStoreStmt(NodeID src, NodeID dst, const ICFGNode* val);
|
|
913
921
|
void addStoreStmt(StoreStmt* edge, SVFVar* src, SVFVar* dst);
|
|
914
|
-
/// Add Call edge
|
|
922
|
+
/// Add Call edge (phi-like: merges actual params from all call sites into formal param)
|
|
915
923
|
CallPE* addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs,
|
|
916
924
|
const FunEntryICFGNode* entry);
|
|
917
925
|
void addCallPE(CallPE* edge, SVFVar* src, SVFVar* dst);
|
|
@@ -335,10 +335,8 @@ public:
|
|
|
335
335
|
edge->getEdgeKind() == SVFStmt::Copy ||
|
|
336
336
|
edge->getEdgeKind() == SVFStmt::Store ||
|
|
337
337
|
edge->getEdgeKind() == SVFStmt::Load ||
|
|
338
|
-
edge->getEdgeKind() == SVFStmt::Call ||
|
|
339
338
|
edge->getEdgeKind() == SVFStmt::Ret ||
|
|
340
339
|
edge->getEdgeKind() == SVFStmt::Gep ||
|
|
341
|
-
edge->getEdgeKind() == SVFStmt::ThreadFork ||
|
|
342
340
|
edge->getEdgeKind() == SVFStmt::ThreadJoin;
|
|
343
341
|
}
|
|
344
342
|
static inline bool classof(const GenericPAGEdgeTy* edge)
|
|
@@ -347,10 +345,8 @@ public:
|
|
|
347
345
|
edge->getEdgeKind() == SVFStmt::Copy ||
|
|
348
346
|
edge->getEdgeKind() == SVFStmt::Store ||
|
|
349
347
|
edge->getEdgeKind() == SVFStmt::Load ||
|
|
350
|
-
edge->getEdgeKind() == SVFStmt::Call ||
|
|
351
348
|
edge->getEdgeKind() == SVFStmt::Ret ||
|
|
352
349
|
edge->getEdgeKind() == SVFStmt::Gep ||
|
|
353
|
-
edge->getEdgeKind() == SVFStmt::ThreadFork ||
|
|
354
350
|
edge->getEdgeKind() == SVFStmt::ThreadJoin;
|
|
355
351
|
}
|
|
356
352
|
//@}
|
|
@@ -693,67 +689,6 @@ public:
|
|
|
693
689
|
};
|
|
694
690
|
|
|
695
691
|
|
|
696
|
-
/*!
|
|
697
|
-
* Call
|
|
698
|
-
*/
|
|
699
|
-
class CallPE: public AssignStmt
|
|
700
|
-
{
|
|
701
|
-
friend class GraphDBClient;
|
|
702
|
-
|
|
703
|
-
private:
|
|
704
|
-
CallPE(const CallPE&); ///< place holder
|
|
705
|
-
void operator=(const CallPE&); ///< place holder
|
|
706
|
-
|
|
707
|
-
const CallICFGNode* call; /// the callsite statement calling from
|
|
708
|
-
const FunEntryICFGNode* entry; /// the function exit statement calling to
|
|
709
|
-
|
|
710
|
-
public:
|
|
711
|
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
712
|
-
//@{
|
|
713
|
-
static inline bool classof(const CallPE*)
|
|
714
|
-
{
|
|
715
|
-
return true;
|
|
716
|
-
}
|
|
717
|
-
static inline bool classof(const SVFStmt* edge)
|
|
718
|
-
{
|
|
719
|
-
return edge->getEdgeKind() == SVFStmt::Call ||
|
|
720
|
-
edge->getEdgeKind() == SVFStmt::ThreadFork;
|
|
721
|
-
}
|
|
722
|
-
static inline bool classof(const GenericPAGEdgeTy* edge)
|
|
723
|
-
{
|
|
724
|
-
return edge->getEdgeKind() == SVFStmt::Call ||
|
|
725
|
-
edge->getEdgeKind() == SVFStmt::ThreadFork;
|
|
726
|
-
}
|
|
727
|
-
//@}
|
|
728
|
-
|
|
729
|
-
/// constructor
|
|
730
|
-
CallPE(SVFVar* s, SVFVar* d, const CallICFGNode* i,
|
|
731
|
-
const FunEntryICFGNode* e, GEdgeKind k = SVFStmt::Call);
|
|
732
|
-
|
|
733
|
-
/// Get method for the call instruction
|
|
734
|
-
//@{
|
|
735
|
-
inline const CallICFGNode* getCallInst() const
|
|
736
|
-
{
|
|
737
|
-
return call;
|
|
738
|
-
}
|
|
739
|
-
inline const CallICFGNode* getCallSite() const
|
|
740
|
-
{
|
|
741
|
-
return call;
|
|
742
|
-
}
|
|
743
|
-
inline const FunEntryICFGNode* getFunEntryICFGNode() const
|
|
744
|
-
{
|
|
745
|
-
return entry;
|
|
746
|
-
}
|
|
747
|
-
//@}
|
|
748
|
-
|
|
749
|
-
const ValVar* getRHSVar() const;
|
|
750
|
-
const ValVar* getLHSVar() const;
|
|
751
|
-
const ValVar* getSrcNode() const;
|
|
752
|
-
const ValVar* getDstNode() const;
|
|
753
|
-
|
|
754
|
-
virtual const std::string toString() const override;
|
|
755
|
-
};
|
|
756
|
-
|
|
757
692
|
/*!
|
|
758
693
|
* Return
|
|
759
694
|
*/
|
|
@@ -850,12 +785,14 @@ public:
|
|
|
850
785
|
static inline bool classof(const SVFStmt* node)
|
|
851
786
|
{
|
|
852
787
|
return node->getEdgeKind() == Phi || node->getEdgeKind() == Select ||
|
|
853
|
-
node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp
|
|
788
|
+
node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp ||
|
|
789
|
+
node->getEdgeKind() == Call || node->getEdgeKind() == ThreadFork;
|
|
854
790
|
}
|
|
855
791
|
static inline bool classof(const GenericPAGEdgeTy* node)
|
|
856
792
|
{
|
|
857
793
|
return node->getEdgeKind() == Phi || node->getEdgeKind() == Select ||
|
|
858
|
-
node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp
|
|
794
|
+
node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp ||
|
|
795
|
+
node->getEdgeKind() == Call || node->getEdgeKind() == ThreadFork;
|
|
859
796
|
}
|
|
860
797
|
//@}
|
|
861
798
|
/// Operands and result at a BinaryNode e.g., p = q + r, `p` is resVar and
|
|
@@ -891,6 +828,81 @@ public:
|
|
|
891
828
|
//@}
|
|
892
829
|
};
|
|
893
830
|
|
|
831
|
+
/*!
|
|
832
|
+
* Call
|
|
833
|
+
* CallPE is a phi-like statement at function entry that merges actual parameters
|
|
834
|
+
* from all call sites into the formal parameter.
|
|
835
|
+
* e.g., formal_param = CallPE(actual1@callsite1, actual2@callsite2, ...)
|
|
836
|
+
*/
|
|
837
|
+
class CallPE: public MultiOpndStmt
|
|
838
|
+
{
|
|
839
|
+
friend class GraphDBClient;
|
|
840
|
+
|
|
841
|
+
public:
|
|
842
|
+
typedef std::vector<const CallICFGNode*> CallICFGNodeVec;
|
|
843
|
+
|
|
844
|
+
private:
|
|
845
|
+
CallPE(const CallPE&); ///< place holder
|
|
846
|
+
void operator=(const CallPE&); ///< place holder
|
|
847
|
+
|
|
848
|
+
CallICFGNodeVec opCallICFGNodes; /// each operand's call site
|
|
849
|
+
const FunEntryICFGNode* entry; /// the function entry node
|
|
850
|
+
|
|
851
|
+
public:
|
|
852
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
853
|
+
//@{
|
|
854
|
+
static inline bool classof(const CallPE*)
|
|
855
|
+
{
|
|
856
|
+
return true;
|
|
857
|
+
}
|
|
858
|
+
static inline bool classof(const SVFStmt* edge)
|
|
859
|
+
{
|
|
860
|
+
return edge->getEdgeKind() == SVFStmt::Call ||
|
|
861
|
+
edge->getEdgeKind() == SVFStmt::ThreadFork;
|
|
862
|
+
}
|
|
863
|
+
static inline bool classof(const GenericPAGEdgeTy* edge)
|
|
864
|
+
{
|
|
865
|
+
return edge->getEdgeKind() == SVFStmt::Call ||
|
|
866
|
+
edge->getEdgeKind() == SVFStmt::ThreadFork;
|
|
867
|
+
}
|
|
868
|
+
//@}
|
|
869
|
+
|
|
870
|
+
/// constructor
|
|
871
|
+
CallPE(ValVar* res, const OPVars& opnds,
|
|
872
|
+
const CallICFGNodeVec& icfgNodes,
|
|
873
|
+
const FunEntryICFGNode* e,
|
|
874
|
+
GEdgeKind k = SVFStmt::Call);
|
|
875
|
+
|
|
876
|
+
/// Add an operand (actual param) from a call site
|
|
877
|
+
void addOpVar(ValVar* op, const CallICFGNode* call)
|
|
878
|
+
{
|
|
879
|
+
opVars.push_back(op);
|
|
880
|
+
opCallICFGNodes.push_back(call);
|
|
881
|
+
assert(opVars.size() == opCallICFGNodes.size() &&
|
|
882
|
+
"Numbers of operands and their CallICFGNodes are not consistent?");
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/// Return the CallICFGNode of the i-th operand
|
|
886
|
+
inline const CallICFGNode* getOpCallICFGNode(u32_t op_idx) const
|
|
887
|
+
{
|
|
888
|
+
return opCallICFGNodes.at(op_idx);
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/// Return all call site ICFGNodes
|
|
892
|
+
inline const CallICFGNodeVec& getOpCallICFGNodes() const
|
|
893
|
+
{
|
|
894
|
+
return opCallICFGNodes;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/// Return the function entry node
|
|
898
|
+
inline const FunEntryICFGNode* getFunEntryICFGNode() const
|
|
899
|
+
{
|
|
900
|
+
return entry;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
virtual const std::string toString() const override;
|
|
904
|
+
};
|
|
905
|
+
|
|
894
906
|
/*!
|
|
895
907
|
* Phi statement (e.g., p = phi(q,r) which receives values from variables q and r from different paths)
|
|
896
908
|
* it is typically at a joint point of the control-flow graph
|
|
@@ -1340,17 +1352,13 @@ public:
|
|
|
1340
1352
|
//@}
|
|
1341
1353
|
|
|
1342
1354
|
/// constructor
|
|
1343
|
-
TDForkPE(
|
|
1344
|
-
const
|
|
1345
|
-
|
|
1355
|
+
TDForkPE(ValVar* res, const OPVars& opnds,
|
|
1356
|
+
const CallICFGNodeVec& icfgNodes,
|
|
1357
|
+
const FunEntryICFGNode* e)
|
|
1358
|
+
: CallPE(res, opnds, icfgNodes, e, SVFStmt::ThreadFork)
|
|
1346
1359
|
{
|
|
1347
1360
|
}
|
|
1348
1361
|
|
|
1349
|
-
const ValVar* getRHSVar() const;
|
|
1350
|
-
const ValVar* getLHSVar() const;
|
|
1351
|
-
const ValVar* getSrcNode() const;
|
|
1352
|
-
const ValVar* getDstNode() const;
|
|
1353
|
-
|
|
1354
1362
|
virtual const std::string toString() const;
|
|
1355
1363
|
|
|
1356
1364
|
};
|
|
@@ -2229,16 +2229,34 @@ class BasicBlockValVar: public ValVar
|
|
|
2229
2229
|
friend class GraphDBClient;
|
|
2230
2230
|
|
|
2231
2231
|
public:
|
|
2232
|
-
static inline bool classof(const BasicBlockValVar*)
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
static inline bool classof(const
|
|
2232
|
+
static inline bool classof(const BasicBlockValVar*)
|
|
2233
|
+
{
|
|
2234
|
+
return true;
|
|
2235
|
+
}
|
|
2236
|
+
static inline bool classof(const SVFVar* node)
|
|
2237
|
+
{
|
|
2238
|
+
return node->getNodeKind() == SVFVar::BasicBlockValNode;
|
|
2239
|
+
}
|
|
2240
|
+
static inline bool classof(const ValVar* node)
|
|
2241
|
+
{
|
|
2242
|
+
return node->getNodeKind() == SVFVar::BasicBlockValNode;
|
|
2243
|
+
}
|
|
2244
|
+
static inline bool classof(const GenericPAGNodeTy* node)
|
|
2245
|
+
{
|
|
2246
|
+
return node->getNodeKind() == SVFVar::BasicBlockValNode;
|
|
2247
|
+
}
|
|
2248
|
+
static inline bool classof(const SVFValue* node)
|
|
2249
|
+
{
|
|
2250
|
+
return node->getNodeKind() == SVFVar::BasicBlockValNode;
|
|
2251
|
+
}
|
|
2237
2252
|
|
|
2238
2253
|
BasicBlockValVar(NodeID i, const SVFType* svfType)
|
|
2239
2254
|
: ValVar(i, svfType, nullptr, BasicBlockValNode) {}
|
|
2240
2255
|
|
|
2241
|
-
inline const std::string getValueName() const
|
|
2256
|
+
inline const std::string getValueName() const
|
|
2257
|
+
{
|
|
2258
|
+
return "basicBlockVal";
|
|
2259
|
+
}
|
|
2242
2260
|
virtual const std::string toString() const;
|
|
2243
2261
|
};
|
|
2244
2262
|
|
|
@@ -2253,16 +2271,34 @@ class AsmPCValVar: public ValVar
|
|
|
2253
2271
|
friend class GraphDBClient;
|
|
2254
2272
|
|
|
2255
2273
|
public:
|
|
2256
|
-
static inline bool classof(const AsmPCValVar*)
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
static inline bool classof(const
|
|
2274
|
+
static inline bool classof(const AsmPCValVar*)
|
|
2275
|
+
{
|
|
2276
|
+
return true;
|
|
2277
|
+
}
|
|
2278
|
+
static inline bool classof(const SVFVar* node)
|
|
2279
|
+
{
|
|
2280
|
+
return node->getNodeKind() == SVFVar::AsmPCValNode;
|
|
2281
|
+
}
|
|
2282
|
+
static inline bool classof(const ValVar* node)
|
|
2283
|
+
{
|
|
2284
|
+
return node->getNodeKind() == SVFVar::AsmPCValNode;
|
|
2285
|
+
}
|
|
2286
|
+
static inline bool classof(const GenericPAGNodeTy* node)
|
|
2287
|
+
{
|
|
2288
|
+
return node->getNodeKind() == SVFVar::AsmPCValNode;
|
|
2289
|
+
}
|
|
2290
|
+
static inline bool classof(const SVFValue* node)
|
|
2291
|
+
{
|
|
2292
|
+
return node->getNodeKind() == SVFVar::AsmPCValNode;
|
|
2293
|
+
}
|
|
2261
2294
|
|
|
2262
2295
|
AsmPCValVar(NodeID i, const SVFType* svfType)
|
|
2263
2296
|
: ValVar(i, svfType, nullptr, AsmPCValNode) {}
|
|
2264
2297
|
|
|
2265
|
-
inline const std::string getValueName() const
|
|
2298
|
+
inline const std::string getValueName() const
|
|
2299
|
+
{
|
|
2300
|
+
return "asmPCVal";
|
|
2301
|
+
}
|
|
2266
2302
|
virtual const std::string toString() const;
|
|
2267
2303
|
};
|
|
2268
2304
|
|
|
@@ -1222,12 +1222,24 @@ void AbstractInterpretation::updateStateOnPhi(const PhiStmt *phi)
|
|
|
1222
1222
|
}
|
|
1223
1223
|
|
|
1224
1224
|
|
|
1225
|
+
/// Handle CallPE: phi-like merging of actual parameters from all call sites
|
|
1226
|
+
/// into the formal parameter at FunEntryICFGNode (e.g., formal = join(actual1@cs1, actual2@cs2, ...))
|
|
1225
1227
|
void AbstractInterpretation::updateStateOnCall(const CallPE *callPE)
|
|
1226
1228
|
{
|
|
1227
1229
|
AbstractState& as = getAbstractState(callPE->getICFGNode());
|
|
1228
|
-
NodeID
|
|
1229
|
-
|
|
1230
|
-
|
|
1230
|
+
NodeID res = callPE->getResID();
|
|
1231
|
+
AbstractValue rhs;
|
|
1232
|
+
for (u32_t i = 0; i < callPE->getOpVarNum(); i++)
|
|
1233
|
+
{
|
|
1234
|
+
NodeID curId = callPE->getOpVarID(i);
|
|
1235
|
+
const ICFGNode* opICFGNode = callPE->getOpCallICFGNode(i);
|
|
1236
|
+
if (hasAbstractState(opICFGNode))
|
|
1237
|
+
{
|
|
1238
|
+
AbstractState& opAs = getAbstractState(opICFGNode);
|
|
1239
|
+
rhs.join_with(opAs[curId]);
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
as[res] = rhs;
|
|
1231
1243
|
}
|
|
1232
1244
|
|
|
1233
1245
|
void AbstractInterpretation::updateStateOnRet(const RetPE *retPE)
|
package/svf/lib/Graphs/ConsG.cpp
CHANGED
|
@@ -86,8 +86,9 @@ void ConstraintGraph::buildCG()
|
|
|
86
86
|
for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter =
|
|
87
87
|
calls.end(); iter != eiter; ++iter)
|
|
88
88
|
{
|
|
89
|
-
const CallPE*
|
|
90
|
-
|
|
89
|
+
const CallPE* callPE = SVFUtil::cast<CallPE>(*iter);
|
|
90
|
+
for(u32_t i = 0; i < callPE->getOpVarNum(); i++)
|
|
91
|
+
addCopyCGEdge(callPE->getOpVarID(i), callPE->getResID());
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
SVFStmt::SVFStmtSetTy& rets = getSVFStmtSet(SVFStmt::Ret);
|
|
@@ -102,8 +103,9 @@ void ConstraintGraph::buildCG()
|
|
|
102
103
|
for (SVFStmt::SVFStmtSetTy::iterator iter = tdfks.begin(), eiter =
|
|
103
104
|
tdfks.end(); iter != eiter; ++iter)
|
|
104
105
|
{
|
|
105
|
-
const TDForkPE*
|
|
106
|
-
|
|
106
|
+
const TDForkPE* forkPE = SVFUtil::cast<TDForkPE>(*iter);
|
|
107
|
+
for(u32_t i = 0; i < forkPE->getOpVarNum(); i++)
|
|
108
|
+
addCopyCGEdge(forkPE->getOpVarID(i), forkPE->getResID());
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
SVFStmt::SVFStmtSetTy& tdjns = getSVFStmtSet(SVFStmt::ThreadJoin);
|
package/svf/lib/Graphs/ICFG.cpp
CHANGED
|
@@ -444,17 +444,7 @@ void ICFG::updateCallGraph(CallGraph* callgraph)
|
|
|
444
444
|
{
|
|
445
445
|
FunEntryICFGNode* calleeEntryNode = getFunEntryBlock(callee);
|
|
446
446
|
FunExitICFGNode* calleeExitNode = getFunExitBlock(callee);
|
|
447
|
-
|
|
448
|
-
{
|
|
449
|
-
for (const SVFStmt *stmt : callBlockNode->getSVFStmts())
|
|
450
|
-
{
|
|
451
|
-
if(const CallPE *callPE = SVFUtil::dyn_cast<CallPE>(stmt))
|
|
452
|
-
{
|
|
453
|
-
if(callPE->getFunEntryICFGNode() == calleeEntryNode)
|
|
454
|
-
SVFUtil::cast<CallCFGEdge>(callEdge)->addCallPE(callPE);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
447
|
+
addCallEdge(callBlockNode, calleeEntryNode);
|
|
458
448
|
if(ICFGEdge* retEdge = addRetEdge(calleeExitNode, retBlockNode))
|
|
459
449
|
{
|
|
460
450
|
for (const SVFStmt *stmt : retBlockNode->getSVFStmts())
|
|
@@ -514,7 +514,7 @@ struct DOTGraphTraits<IRGraph*> : public DefaultDOTGraphTraits
|
|
|
514
514
|
assert(edge && "No edge found!!");
|
|
515
515
|
if(const CallPE* calledge = SVFUtil::dyn_cast<CallPE>(edge))
|
|
516
516
|
{
|
|
517
|
-
return calledge->
|
|
517
|
+
return calledge->getFunEntryICFGNode()->getSourceLoc();
|
|
518
518
|
}
|
|
519
519
|
else if(const RetPE* retedge = SVFUtil::dyn_cast<RetPE>(edge))
|
|
520
520
|
{
|
package/svf/lib/Graphs/VFG.cpp
CHANGED
|
@@ -499,7 +499,8 @@ void VFG::addVFGNodes()
|
|
|
499
499
|
forks.end(); iter != eiter; ++iter)
|
|
500
500
|
{
|
|
501
501
|
TDForkPE* forkedge = SVFUtil::cast<TDForkPE>(*iter);
|
|
502
|
-
|
|
502
|
+
for(u32_t i = 0; i < forkedge->getOpVarNum(); i++)
|
|
503
|
+
addActualParmVFGNode(forkedge->getOpVar(i), forkedge->getOpCallICFGNode(i));
|
|
503
504
|
}
|
|
504
505
|
|
|
505
506
|
// initialize actual parameter nodes
|
|
@@ -538,18 +539,8 @@ void VFG::addVFGNodes()
|
|
|
538
539
|
if (isInterestedSVFVar(param) == false || hasBlackHoleConstObjAddrAsDef(param))
|
|
539
540
|
continue;
|
|
540
541
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
{
|
|
544
|
-
for (SVFStmt::SVFStmtSetTy::const_iterator cit = param->getIncomingEdgesBegin(SVFStmt::Call), ecit =
|
|
545
|
-
param->getIncomingEdgesEnd(SVFStmt::Call); cit != ecit; ++cit)
|
|
546
|
-
{
|
|
547
|
-
CallPE* callPE = SVFUtil::cast<CallPE>(*cit);
|
|
548
|
-
if (isInterestedSVFVar(callPE->getRHSVar()))
|
|
549
|
-
callPEs.insert(callPE);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
addFormalParmVFGNode(param,func,callPEs);
|
|
542
|
+
const CallPE* callPE = pag->getCallPEForFormalParm(param);
|
|
543
|
+
addFormalParmVFGNode(param,func,callPE);
|
|
553
544
|
}
|
|
554
545
|
|
|
555
546
|
if (func->isVarArg())
|
|
@@ -558,18 +549,8 @@ void VFG::addVFGNodes()
|
|
|
558
549
|
if (isInterestedSVFVar(varParam) == false || hasBlackHoleConstObjAddrAsDef(varParam))
|
|
559
550
|
continue;
|
|
560
551
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
{
|
|
564
|
-
for(SVFStmt::SVFStmtSetTy::const_iterator cit = varParam->getIncomingEdgesBegin(SVFStmt::Call),
|
|
565
|
-
ecit = varParam->getIncomingEdgesEnd(SVFStmt::Call); cit!=ecit; ++cit)
|
|
566
|
-
{
|
|
567
|
-
CallPE* callPE = SVFUtil::cast<CallPE>(*cit);
|
|
568
|
-
if(isInterestedSVFVar(callPE->getRHSVar()))
|
|
569
|
-
callPEs.insert(callPE);
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
addFormalParmVFGNode(varParam,func,callPEs);
|
|
552
|
+
const CallPE* varCallPE = pag->getCallPEForFormalParm(varParam);
|
|
553
|
+
addFormalParmVFGNode(varParam,func,varCallPE);
|
|
573
554
|
}
|
|
574
555
|
}
|
|
575
556
|
|
|
@@ -802,12 +783,17 @@ void VFG::connectDirectVFGEdges()
|
|
|
802
783
|
}
|
|
803
784
|
else if(FormalParmVFGNode* formalParm = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
|
|
804
785
|
{
|
|
805
|
-
|
|
806
|
-
it!=eit; ++it)
|
|
786
|
+
if(const CallPE* callPE = formalParm->getCallPE())
|
|
807
787
|
{
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
788
|
+
for(u32_t i = 0; i < callPE->getOpVarNum(); i++)
|
|
789
|
+
{
|
|
790
|
+
if(isInterestedSVFVar(callPE->getOpVar(i)))
|
|
791
|
+
{
|
|
792
|
+
const CallICFGNode* cs = callPE->getOpCallICFGNode(i);
|
|
793
|
+
ActualParmVFGNode* acutalParm = getActualParmVFGNode(callPE->getOpVar(i), cs);
|
|
794
|
+
addInterEdgeFromAPToFP(acutalParm,formalParm,getCallSiteID(cs, formalParm->getFun()));
|
|
795
|
+
}
|
|
796
|
+
}
|
|
811
797
|
}
|
|
812
798
|
}
|
|
813
799
|
else if(FormalRetVFGNode* calleeRet = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
|
|
@@ -836,9 +822,16 @@ void VFG::connectDirectVFGEdges()
|
|
|
836
822
|
forks.end(); iter != eiter; ++iter)
|
|
837
823
|
{
|
|
838
824
|
TDForkPE* forkedge = SVFUtil::cast<TDForkPE>(*iter);
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
825
|
+
FormalParmVFGNode* formalParm = getFormalParmVFGNode(forkedge->getRes());
|
|
826
|
+
for(u32_t i = 0; i < forkedge->getOpVarNum(); i++)
|
|
827
|
+
{
|
|
828
|
+
if(isInterestedSVFVar(forkedge->getOpVar(i)))
|
|
829
|
+
{
|
|
830
|
+
const CallICFGNode* cs = forkedge->getOpCallICFGNode(i);
|
|
831
|
+
ActualParmVFGNode* acutalParm = getActualParmVFGNode(forkedge->getOpVar(i), cs);
|
|
832
|
+
addInterEdgeFromAPToFP(acutalParm,formalParm,getCallSiteID(cs, formalParm->getFun()));
|
|
833
|
+
}
|
|
834
|
+
}
|
|
842
835
|
}
|
|
843
836
|
/// add join edge
|
|
844
837
|
SVFStmt::SVFStmtSetTy& joins = getSVFStmtSet(SVFStmt::ThreadJoin);
|
|
@@ -231,7 +231,7 @@ void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID,
|
|
|
231
231
|
else if (edge == "variant-gep")
|
|
232
232
|
pag->addVariantGepStmt(srcID, dstID, AccessPath(offsetOrCSId));
|
|
233
233
|
else if (edge == "call")
|
|
234
|
-
pag->addEdge(srcNode, dstNode, new CallPE(
|
|
234
|
+
pag->addEdge(srcNode, dstNode, new CallPE(SVFUtil::cast<ValVar>(dstNode), {SVFUtil::cast<ValVar>(srcNode)}, {nullptr}, nullptr));
|
|
235
235
|
else if (edge == "ret")
|
|
236
236
|
pag->addEdge(srcNode, dstNode, new RetPE(srcNode, dstNode, nullptr,nullptr));
|
|
237
237
|
else if (edge == "cmp")
|
package/svf/lib/SVFIR/SVFIR.cpp
CHANGED
|
@@ -305,26 +305,33 @@ void SVFIR::addStoreStmt(StoreStmt* edge, SVFVar* src, SVFVar* dst)
|
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
/*!
|
|
308
|
-
* Add Call edge
|
|
308
|
+
* Add Call edge (phi-like: merges actual params from all call sites into formal param)
|
|
309
309
|
*/
|
|
310
310
|
CallPE* SVFIR::addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry)
|
|
311
311
|
{
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
312
|
+
ValVar* opNode = const_cast<ValVar*>(getValVar(src));
|
|
313
|
+
ValVar* resNode = const_cast<ValVar*>(getValVar(dst));
|
|
314
|
+
FParmToCallPEMap::iterator it = fParmToCallPEMap.find(resNode);
|
|
315
|
+
// if first operand, create a new CallPE, otherwise add the operand to the existing CallPE
|
|
316
|
+
if(it == fParmToCallPEMap.end())
|
|
317
317
|
{
|
|
318
|
-
CallPE* callPE = new CallPE(
|
|
319
|
-
addCallPE(callPE,
|
|
318
|
+
CallPE* callPE = new CallPE(resNode, {opNode}, {cs}, entry);
|
|
319
|
+
addCallPE(callPE, opNode, resNode);
|
|
320
320
|
return callPE;
|
|
321
321
|
}
|
|
322
|
+
else
|
|
323
|
+
{
|
|
324
|
+
it->second->addOpVar(opNode, cs);
|
|
325
|
+
/// return null if we already added this CallPE
|
|
326
|
+
return nullptr;
|
|
327
|
+
}
|
|
322
328
|
}
|
|
323
329
|
|
|
324
330
|
void SVFIR::addCallPE(CallPE* edge, SVFVar* src, SVFVar* dst)
|
|
325
331
|
{
|
|
326
332
|
addToStmt2TypeMap(edge);
|
|
327
|
-
addEdge(src,dst, edge);
|
|
333
|
+
addEdge(src, dst, edge);
|
|
334
|
+
fParmToCallPEMap[dst] = edge;
|
|
328
335
|
}
|
|
329
336
|
|
|
330
337
|
/*!
|
|
@@ -366,16 +373,23 @@ SVFStmt* SVFIR::addBlackHoleAddrStmt(NodeID node)
|
|
|
366
373
|
*/
|
|
367
374
|
TDForkPE* SVFIR::addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry)
|
|
368
375
|
{
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
376
|
+
ValVar* opNode = const_cast<ValVar*>(getValVar(src));
|
|
377
|
+
ValVar* resNode = const_cast<ValVar*>(getValVar(dst));
|
|
378
|
+
FParmToCallPEMap::iterator it = fParmToCallPEMap.find(resNode);
|
|
379
|
+
// if first operand, create a new TDForkPE, otherwise add the operand to the existing TDForkPE
|
|
380
|
+
if(it == fParmToCallPEMap.end())
|
|
374
381
|
{
|
|
375
|
-
TDForkPE* forkPE = new TDForkPE(
|
|
376
|
-
|
|
382
|
+
TDForkPE* forkPE = new TDForkPE(resNode, {opNode}, {cs}, entry);
|
|
383
|
+
addToStmt2TypeMap(forkPE);
|
|
384
|
+
addEdge(opNode, resNode, forkPE);
|
|
385
|
+
fParmToCallPEMap[resNode] = forkPE;
|
|
377
386
|
return forkPE;
|
|
378
387
|
}
|
|
388
|
+
else
|
|
389
|
+
{
|
|
390
|
+
it->second->addOpVar(opNode, cs);
|
|
391
|
+
return nullptr;
|
|
392
|
+
}
|
|
379
393
|
}
|
|
380
394
|
|
|
381
395
|
/*!
|
|
@@ -242,7 +242,14 @@ const std::string CallPE::toString() const
|
|
|
242
242
|
{
|
|
243
243
|
std::string str;
|
|
244
244
|
std::stringstream rawstr(str);
|
|
245
|
-
rawstr << "CallPE: [Var" <<
|
|
245
|
+
rawstr << "CallPE: [Var" << getResID() << " <-- (";
|
|
246
|
+
for (u32_t i = 0; i < getOpVarNum(); i++)
|
|
247
|
+
{
|
|
248
|
+
rawstr << "[Var" << getOpVarID(i) << ", ICFGNode" << getOpCallICFGNode(i)->getId() << "]";
|
|
249
|
+
if (i + 1 < getOpVarNum())
|
|
250
|
+
rawstr << ", ";
|
|
251
|
+
}
|
|
252
|
+
rawstr << ")] ";
|
|
246
253
|
if (Options::ShowSVFIRValue())
|
|
247
254
|
{
|
|
248
255
|
rawstr << "\n";
|
|
@@ -268,7 +275,14 @@ const std::string TDForkPE::toString() const
|
|
|
268
275
|
{
|
|
269
276
|
std::string str;
|
|
270
277
|
std::stringstream rawstr(str);
|
|
271
|
-
rawstr << "TDForkPE: [Var" <<
|
|
278
|
+
rawstr << "TDForkPE: [Var" << getResID() << " <-- (";
|
|
279
|
+
for (u32_t i = 0; i < getOpVarNum(); i++)
|
|
280
|
+
{
|
|
281
|
+
rawstr << "[Var" << getOpVarID(i) << ", ICFGNode" << getOpCallICFGNode(i)->getId() << "]";
|
|
282
|
+
if (i + 1 < getOpVarNum())
|
|
283
|
+
rawstr << ", ";
|
|
284
|
+
}
|
|
285
|
+
rawstr << ")] ";
|
|
272
286
|
if (Options::ShowSVFIRValue())
|
|
273
287
|
{
|
|
274
288
|
rawstr << "\n";
|
|
@@ -375,22 +389,6 @@ const ValVar* GepStmt::getDstNode() const
|
|
|
375
389
|
return getLHSVar();
|
|
376
390
|
}
|
|
377
391
|
|
|
378
|
-
const ValVar* CallPE::getRHSVar() const
|
|
379
|
-
{
|
|
380
|
-
return cast<ValVar>(SVFStmt::getSrcNode());
|
|
381
|
-
}
|
|
382
|
-
const ValVar* CallPE::getLHSVar() const
|
|
383
|
-
{
|
|
384
|
-
return cast<ValVar>(SVFStmt::getDstNode());
|
|
385
|
-
}
|
|
386
|
-
const ValVar* CallPE::getSrcNode() const
|
|
387
|
-
{
|
|
388
|
-
return getRHSVar();
|
|
389
|
-
}
|
|
390
|
-
const ValVar* CallPE::getDstNode() const
|
|
391
|
-
{
|
|
392
|
-
return getLHSVar();
|
|
393
|
-
}
|
|
394
392
|
|
|
395
393
|
const ValVar* RetPE::getRHSVar() const
|
|
396
394
|
{
|
|
@@ -409,22 +407,6 @@ const ValVar* RetPE::getDstNode() const
|
|
|
409
407
|
return getLHSVar();
|
|
410
408
|
}
|
|
411
409
|
|
|
412
|
-
const ValVar* TDForkPE::getRHSVar() const
|
|
413
|
-
{
|
|
414
|
-
return cast<ValVar>(SVFStmt::getSrcNode());
|
|
415
|
-
}
|
|
416
|
-
const ValVar* TDForkPE::getLHSVar() const
|
|
417
|
-
{
|
|
418
|
-
return cast<ValVar>(SVFStmt::getDstNode());
|
|
419
|
-
}
|
|
420
|
-
const ValVar* TDForkPE::getSrcNode() const
|
|
421
|
-
{
|
|
422
|
-
return getRHSVar();
|
|
423
|
-
}
|
|
424
|
-
const ValVar* TDForkPE::getDstNode() const
|
|
425
|
-
{
|
|
426
|
-
return getLHSVar();
|
|
427
|
-
}
|
|
428
410
|
|
|
429
411
|
const ValVar* TDJoinPE::getRHSVar() const
|
|
430
412
|
{
|
|
@@ -518,10 +500,16 @@ StoreStmt::StoreStmt(SVFVar* s, SVFVar* d, const ICFGNode* st)
|
|
|
518
500
|
{
|
|
519
501
|
}
|
|
520
502
|
|
|
521
|
-
CallPE::CallPE(
|
|
522
|
-
const
|
|
523
|
-
|
|
503
|
+
CallPE::CallPE(ValVar* res, const OPVars& opnds,
|
|
504
|
+
const CallICFGNodeVec& icfgNodes,
|
|
505
|
+
const FunEntryICFGNode* e,
|
|
506
|
+
GEdgeKind k)
|
|
507
|
+
: MultiOpndStmt(res, opnds,
|
|
508
|
+
makeEdgeFlagWithAddionalOpnd(k, opnds.at(0))),
|
|
509
|
+
opCallICFGNodes(icfgNodes), entry(e)
|
|
524
510
|
{
|
|
511
|
+
assert(opnds.size() == icfgNodes.size() &&
|
|
512
|
+
"Numbers of operands and their CallICFGNodes are not consistent?");
|
|
525
513
|
}
|
|
526
514
|
|
|
527
515
|
|
|
@@ -1767,12 +1767,18 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge)
|
|
|
1767
1767
|
{
|
|
1768
1768
|
icfgNode = pag->getICFG()->getFunExitICFGNode(llvmMS->getFunObjVar(curInst->getFunction()));
|
|
1769
1769
|
}
|
|
1770
|
+
else if(const CallPE* callPE = SVFUtil::dyn_cast<CallPE>(edge))
|
|
1771
|
+
{
|
|
1772
|
+
/// CallPE is placed at FunEntryICFGNode (phi-like merging of actual params)
|
|
1773
|
+
icfgNode = const_cast<FunEntryICFGNode*>(callPE->getFunEntryICFGNode());
|
|
1774
|
+
}
|
|
1775
|
+
else if(SVFUtil::isa<RetPE>(edge))
|
|
1776
|
+
{
|
|
1777
|
+
icfgNode = llvmMS->getRetICFGNode(SVFUtil::cast<Instruction>(curInst));
|
|
1778
|
+
}
|
|
1770
1779
|
else
|
|
1771
1780
|
{
|
|
1772
|
-
|
|
1773
|
-
icfgNode = llvmMS->getRetICFGNode(SVFUtil::cast<Instruction>(curInst));
|
|
1774
|
-
else
|
|
1775
|
-
icfgNode = llvmMS->getICFGNode(SVFUtil::cast<Instruction>(curInst));
|
|
1781
|
+
icfgNode = llvmMS->getICFGNode(SVFUtil::cast<Instruction>(curInst));
|
|
1776
1782
|
}
|
|
1777
1783
|
}
|
|
1778
1784
|
else if (const Argument* arg = SVFUtil::dyn_cast<Argument>(curVal))
|
|
@@ -1801,10 +1807,15 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge)
|
|
|
1801
1807
|
icfgNode->addSVFStmt(edge);
|
|
1802
1808
|
if(const CallPE* callPE = SVFUtil::dyn_cast<CallPE>(edge))
|
|
1803
1809
|
{
|
|
1804
|
-
|
|
1810
|
+
/// CallPE is phi-like at FunEntryICFGNode. Collect it on each CallCFGEdge
|
|
1811
|
+
/// whose call site appears as an operand, so the edge knows which params are passed.
|
|
1805
1812
|
FunEntryICFGNode* entryNode = const_cast<FunEntryICFGNode*>(callPE->getFunEntryICFGNode());
|
|
1806
|
-
|
|
1807
|
-
|
|
1813
|
+
for(u32_t i = 0; i < callPE->getOpVarNum(); i++)
|
|
1814
|
+
{
|
|
1815
|
+
CallICFGNode* callNode = const_cast<CallICFGNode*>(callPE->getOpCallICFGNode(i));
|
|
1816
|
+
if(ICFGEdge* icfgEdge = pag->getICFG()->hasInterICFGEdge(callNode, entryNode, ICFGEdge::CallCF))
|
|
1817
|
+
SVFUtil::cast<CallCFGEdge>(icfgEdge)->addCallPE(callPE);
|
|
1818
|
+
}
|
|
1808
1819
|
}
|
|
1809
1820
|
else if(const RetPE* retPE = SVFUtil::dyn_cast<RetPE>(edge))
|
|
1810
1821
|
{
|