svf-lib 1.0.734 → 1.0.738

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.
@@ -0,0 +1,351 @@
1
+ //===----- CHG.h -- Base class of pointer analyses ---------------------------//
2
+ //
3
+ // SVF: Static Value-Flow Analysis
4
+ //
5
+ // Copyright (C) <2013-2017> <Yulei Sui>
6
+ //
7
+
8
+ // This program is free software: you can redistribute it and/or modify
9
+ // it under the terms of the GNU General Public License as published by
10
+ // the Free Software Foundation, either version 3 of the License, or
11
+ // (at your option) any later version.
12
+
13
+ // This program is distributed in the hope that it will be useful,
14
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ // GNU General Public License for more details.
17
+
18
+ // You should have received a copy of the GNU General Public License
19
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ //
21
+ //===----------------------------------------------------------------------===//
22
+
23
+ /*
24
+ * CHG.h (previously CHA.h)
25
+ *
26
+ * Created on: Apr 13, 2016
27
+ * Author: Xiaokang Fan
28
+ *
29
+ * Created on: Aug 24, 2019
30
+ * Author: Mohamad Barbar
31
+ */
32
+
33
+ #ifndef CHA_H_
34
+ #define CHA_H_
35
+
36
+ #include "Util/SVFModule.h"
37
+ #include "Graphs/GenericGraph.h"
38
+ #include "Util/WorkList.h"
39
+
40
+ namespace SVF
41
+ {
42
+
43
+ class SVFModule;
44
+ class CHNode;
45
+
46
+ typedef Set<const GlobalValue*> VTableSet;
47
+ typedef Set<const SVFFunction*> VFunSet;
48
+
49
+ /// Common base for class hierarchy graph. Only implements what PointerAnalysis needs.
50
+ class CommonCHGraph
51
+ {
52
+ public:
53
+ virtual ~CommonCHGraph() { };
54
+ enum CHGKind
55
+ {
56
+ Standard,
57
+ DI
58
+ };
59
+
60
+ virtual bool csHasVFnsBasedonCHA(CallSite cs) = 0;
61
+ virtual const VFunSet &getCSVFsBasedonCHA(CallSite cs) = 0;
62
+ virtual bool csHasVtblsBasedonCHA(CallSite cs) = 0;
63
+ virtual const VTableSet &getCSVtblsBasedonCHA(CallSite cs) = 0;
64
+ virtual void getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &virtualFunctions) = 0;
65
+
66
+ CHGKind getKind(void) const
67
+ {
68
+ return kind;
69
+ }
70
+
71
+ protected:
72
+ CHGKind kind;
73
+ };
74
+
75
+
76
+ typedef GenericEdge<CHNode> GenericCHEdgeTy;
77
+ class CHEdge: public GenericCHEdgeTy
78
+ {
79
+ public:
80
+ typedef enum
81
+ {
82
+ INHERITANCE = 0x1, // inheritance relation
83
+ INSTANTCE = 0x2 // template-instance relation
84
+ } CHEDGETYPE;
85
+
86
+ typedef GenericNode<CHNode,CHEdge>::GEdgeSetTy CHEdgeSetTy;
87
+
88
+ CHEdge(CHNode *s, CHNode *d, CHEDGETYPE et, GEdgeFlag k = 0):
89
+ GenericCHEdgeTy(s,d,k)
90
+ {
91
+ edgeType = et;
92
+ }
93
+
94
+ CHEDGETYPE getEdgeType() const
95
+ {
96
+ return edgeType;
97
+ }
98
+
99
+ private:
100
+ CHEDGETYPE edgeType;
101
+ };
102
+
103
+ typedef GenericNode<CHNode,CHEdge> GenericCHNodeTy;
104
+ class CHNode: public GenericCHNodeTy
105
+ {
106
+ public:
107
+ typedef enum
108
+ {
109
+ PURE_ABSTRACT = 0x1, // pure virtual abstract class
110
+ MULTI_INHERITANCE = 0x2, // multi inheritance class
111
+ TEMPLATE = 0x04 // template class
112
+ } CLASSATTR;
113
+
114
+ typedef std::vector<const SVFFunction*> FuncVector;
115
+
116
+ CHNode (const std::string name, NodeID i = 0, GNodeK k = 0):
117
+ GenericCHNodeTy(i, k), vtable(nullptr), className(name), flags(0)
118
+ {
119
+ }
120
+ ~CHNode()
121
+ {
122
+ }
123
+ std::string getName() const
124
+ {
125
+ return className;
126
+ }
127
+ /// Flags
128
+ //@{
129
+ inline void setFlag(CLASSATTR mask)
130
+ {
131
+ flags |= mask;
132
+ }
133
+ inline bool hasFlag(CLASSATTR mask) const
134
+ {
135
+ return (flags & mask) == mask;
136
+ }
137
+ //@}
138
+
139
+ /// Attribute
140
+ //@{
141
+ inline void setPureAbstract()
142
+ {
143
+ setFlag(PURE_ABSTRACT);
144
+ }
145
+ inline void setMultiInheritance()
146
+ {
147
+ setFlag(MULTI_INHERITANCE);
148
+ }
149
+ inline void setTemplate()
150
+ {
151
+ setFlag(TEMPLATE);
152
+ }
153
+ inline bool isPureAbstract() const
154
+ {
155
+ return hasFlag(PURE_ABSTRACT);
156
+ }
157
+ inline bool isMultiInheritance() const
158
+ {
159
+ return hasFlag(MULTI_INHERITANCE);
160
+ }
161
+ inline bool isTemplate() const
162
+ {
163
+ return hasFlag(TEMPLATE);
164
+ }
165
+ //@}
166
+
167
+ void addVirtualFunctionVector(FuncVector vfuncvec)
168
+ {
169
+ virtualFunctionVectors.push_back(vfuncvec);
170
+ }
171
+ const std::vector<FuncVector> &getVirtualFunctionVectors() const
172
+ {
173
+ return virtualFunctionVectors;
174
+ }
175
+ void getVirtualFunctions(u32_t idx, FuncVector &virtualFunctions) const;
176
+
177
+ const GlobalValue *getVTable() const
178
+ {
179
+ return vtable;
180
+ }
181
+
182
+ void setVTable(const GlobalValue *vtbl)
183
+ {
184
+ vtable = vtbl;
185
+ }
186
+
187
+ private:
188
+ const GlobalValue* vtable;
189
+ std::string className;
190
+ size_t flags;
191
+ /*
192
+ * virtual functions inherited from different classes are separately stored
193
+ * to model different vtables inherited from different fathers.
194
+ *
195
+ * Example:
196
+ * class C: public A, public B
197
+ * vtableC = {Af1, Af2, ..., inttoptr, Bg1, Bg2, ...} ("inttoptr"
198
+ * instruction works as the delimiter for separating virtual functions
199
+ * inherited from different classes)
200
+ *
201
+ * virtualFunctionVectors = {{Af1, Af2, ...}, {Bg1, Bg2, ...}}
202
+ */
203
+ std::vector<FuncVector> virtualFunctionVectors;
204
+ };
205
+
206
+ /// class hierarchy graph
207
+ typedef GenericGraph<CHNode,CHEdge> GenericCHGraphTy;
208
+ class CHGraph: public CommonCHGraph, public GenericCHGraphTy
209
+ {
210
+ friend class CHGBuilder;
211
+
212
+ public:
213
+ typedef Set<const CHNode*> CHNodeSetTy;
214
+ typedef FIFOWorkList<const CHNode*> WorkList;
215
+ typedef Map<std::string, CHNodeSetTy> NameToCHNodesMap;
216
+ typedef Map<CallSite, CHNodeSetTy> CallSiteToCHNodesMap;
217
+ typedef Map<CallSite, VTableSet> CallSiteToVTableSetMap;
218
+ typedef Map<CallSite, VFunSet> CallSiteToVFunSetMap;
219
+
220
+ typedef enum
221
+ {
222
+ CONSTRUCTOR = 0x1, // connect node based on constructor
223
+ DESTRUCTOR = 0x2 // connect node based on destructor
224
+ } RELATIONTYPE;
225
+
226
+ CHGraph(SVFModule* svfModule): svfMod(svfModule), classNum(0), vfID(0), buildingCHGTime(0)
227
+ {
228
+ this->kind = Standard;
229
+ }
230
+ ~CHGraph() override = default;
231
+
232
+ void addEdge(const std::string className,
233
+ const std::string baseClassName,
234
+ CHEdge::CHEDGETYPE edgeType);
235
+ CHNode *getNode(const std::string name) const;
236
+ void getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override;
237
+ void dump(const std::string& filename);
238
+ void view();
239
+ void printCH();
240
+
241
+ inline s32_t getVirtualFunctionID(const SVFFunction* vfn) const
242
+ {
243
+ Map<const SVFFunction*, s32_t>::const_iterator it =
244
+ virtualFunctionToIDMap.find(vfn);
245
+ if (it != virtualFunctionToIDMap.end())
246
+ return it->second;
247
+ else
248
+ return -1;
249
+ }
250
+ inline const SVFFunction* getVirtualFunctionBasedonID(s32_t id) const
251
+ {
252
+ Map<const SVFFunction*, s32_t>::const_iterator it, eit;
253
+ for (it = virtualFunctionToIDMap.begin(), eit =
254
+ virtualFunctionToIDMap.end(); it != eit; ++it)
255
+ {
256
+ if (it->second == id)
257
+ return it->first;
258
+ }
259
+ return nullptr;
260
+ }
261
+
262
+ inline void addInstances(const std::string templateName, CHNode* node)
263
+ {
264
+ NameToCHNodesMap::iterator it = templateNameToInstancesMap.find(
265
+ templateName);
266
+ if (it != templateNameToInstancesMap.end())
267
+ it->second.insert(node);
268
+ else
269
+ templateNameToInstancesMap[templateName].insert(node);
270
+ }
271
+ inline const CHNodeSetTy &getDescendants(const std::string className)
272
+ {
273
+ return classNameToDescendantsMap[className];
274
+ }
275
+ inline const CHNodeSetTy &getInstances(const std::string className)
276
+ {
277
+ return templateNameToInstancesMap[className];
278
+ }
279
+
280
+ inline bool csHasVtblsBasedonCHA(CallSite cs) override
281
+ {
282
+ CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs);
283
+ return it != csToCHAVtblsMap.end();
284
+ }
285
+ inline bool csHasVFnsBasedonCHA(CallSite cs) override
286
+ {
287
+ CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs);
288
+ return it != csToCHAVFnsMap.end();
289
+ }
290
+ inline const VTableSet &getCSVtblsBasedonCHA(CallSite cs) override
291
+ {
292
+ CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs);
293
+ assert(it != csToCHAVtblsMap.end() && "cs does not have vtabls based on CHA.");
294
+ return it->second;
295
+ }
296
+ inline const VFunSet &getCSVFsBasedonCHA(CallSite cs) override
297
+ {
298
+ CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs);
299
+ assert(it != csToCHAVFnsMap.end() && "cs does not have vfns based on CHA.");
300
+ return it->second;
301
+ }
302
+
303
+ static inline bool classof(const CommonCHGraph *chg)
304
+ {
305
+ return chg->getKind() == Standard;
306
+ }
307
+
308
+
309
+ private:
310
+ SVFModule* svfMod;
311
+ u32_t classNum;
312
+ s32_t vfID;
313
+ double buildingCHGTime;
314
+ Map<std::string, CHNode *> classNameToNodeMap;
315
+ NameToCHNodesMap classNameToDescendantsMap;
316
+ NameToCHNodesMap classNameToAncestorsMap;
317
+ NameToCHNodesMap classNameToInstAndDescsMap;
318
+ NameToCHNodesMap templateNameToInstancesMap;
319
+ CallSiteToCHNodesMap csToClassesMap;
320
+
321
+ Map<const SVFFunction*, s32_t> virtualFunctionToIDMap;
322
+ CallSiteToVTableSetMap csToCHAVtblsMap;
323
+ CallSiteToVFunSetMap csToCHAVFnsMap;
324
+ };
325
+
326
+ } // End namespace SVF
327
+
328
+ namespace llvm
329
+ {
330
+ /* !
331
+ * GraphTraits specializations for generic graph algorithms.
332
+ * Provide graph traits for traversing from a constraint node using standard graph traversals.
333
+ */
334
+ template<> struct GraphTraits<SVF::CHNode*> : public GraphTraits<SVF::GenericNode<SVF::CHNode,SVF::CHEdge>* >
335
+ {
336
+ };
337
+
338
+ /// Inverse GraphTraits specializations for call graph node, it is used for inverse traversal.
339
+ template<>
340
+ struct GraphTraits<Inverse<SVF::CHNode*> > : public GraphTraits<Inverse<SVF::GenericNode<SVF::CHNode,SVF::CHEdge>* > >
341
+ {
342
+ };
343
+
344
+ template<> struct GraphTraits<SVF::CHGraph*> : public GraphTraits<SVF::GenericGraph<SVF::CHNode,SVF::CHEdge>* >
345
+ {
346
+ typedef SVF::CHNode *NodeRef;
347
+ };
348
+
349
+ } // End namespace llvm
350
+
351
+ #endif /* CHA_H_ */
@@ -108,7 +108,7 @@ public:
108
108
  }
109
109
  } equalGEdge;
110
110
 
111
- inline bool operator==(const GenericEdge<NodeType>* rhs) const
111
+ virtual inline bool operator==(const GenericEdge<NodeType>* rhs) const
112
112
  {
113
113
  return (rhs->edgeFlag == this->edgeFlag && rhs->getSrcID() == this->getSrcID()
114
114
  && rhs->getDstID() == this->getDstID());
@@ -51,16 +51,15 @@ public:
51
51
  typedef Set<const SVFStmt*> PAGEdgeSet;
52
52
  typedef Map<const Value*,PAGEdgeSet> ValueToEdgeMap;
53
53
 
54
- private:
54
+ protected:
55
+ SVFStmt::PAGKindToEdgeSetMapTy PAGEdgeKindToSetMap; // < SVFIR edge map containing all PAGEdges
56
+ SVFStmt::PAGKindToEdgeSetMapTy PTAPAGEdgeKindToSetMap; // < SVFIR edge map containing only pointer-related edges, i.e, both RHS and RHS are of pointer type
55
57
  bool fromFile; ///< Whether the SVFIR is built according to user specified data from a txt file
56
58
  NodeID nodeNumAfterPAGBuild; // initial node number after building SVFIR, excluding later added nodes, e.g., gepobj nodes
57
59
  u32_t totalPTAPAGEdge;
58
- SVFStmt::PAGKindToEdgeSetMapTy PAGEdgeKindToSetMap; // < SVFIR edge map containing all PAGEdges
59
- SVFStmt::PAGKindToEdgeSetMapTy PTAPAGEdgeKindToSetMap; // < SVFIR edge map containing only pointer-related edges, i.e, both RHS and RHS are of pointer type
60
60
  ValueToEdgeMap valueToEdgeMap; ///< Map llvm::Values to all corresponding PAGEdges
61
61
  SymbolTableInfo* symInfo;
62
62
 
63
- protected:
64
63
  /// Add a node into the graph
65
64
  inline NodeID addNode(SVFVar* node, NodeID i)
66
65
  {
@@ -75,6 +74,9 @@ protected:
75
74
  /// Return true if this labeled edge exits, including store, call and load
76
75
  /// two store edge can have same dst and src but located in different basic blocks, thus flags are needed to distinguish them
77
76
  SVFStmt* hasLabeledEdge(SVFVar* src, SVFVar* dst, SVFStmt::PEDGEK kind, const ICFGNode* cs);
77
+ /// Return MultiOpndStmt since it has more than one operands (we use operand 2 here to make the flag)
78
+ SVFStmt* hasLabeledEdge(SVFVar* src, SVFVar* op1, SVFStmt::PEDGEK kind, const SVFVar* op2);
79
+
78
80
  /// Map a value to a set of edges
79
81
  inline void mapValueToEdge(const Value *V, SVFStmt *edge)
80
82
  {
@@ -102,17 +104,6 @@ public:
102
104
  {
103
105
  return fromFile;
104
106
  }
105
- /// Get edges set according to its kind
106
- inline SVFStmt::PAGEdgeSetTy& getEdgeSet(SVFStmt::PEDGEK kind)
107
- {
108
- return PAGEdgeKindToSetMap[kind];
109
- }
110
- /// Get PTA edges set according to its kind
111
- inline SVFStmt::PAGEdgeSetTy& getPTAEdgeSet(SVFStmt::PEDGEK kind)
112
- {
113
- return PTAPAGEdgeKindToSetMap[kind];
114
- }
115
-
116
107
  /// Get all SVFIR Edges that corresponds to an LLVM value
117
108
  inline const PAGEdgeSet& getValueEdges(const Value *V)
118
109
  {
@@ -68,6 +68,7 @@ public:
68
68
  typedef Map<const PAGNode*, IntraPHIVFGNode*> PAGNodeToPHIVFGNodeMapTy;
69
69
  typedef Map<const PAGNode*, BinaryOPVFGNode*> PAGNodeToBinaryOPVFGNodeMapTy;
70
70
  typedef Map<const PAGNode*, UnaryOPVFGNode*> PAGNodeToUnaryOPVFGNodeMapTy;
71
+ typedef Map<const PAGNode*, BranchVFGNode*> PAGNodeToBranchVFGNodeMapTy;
71
72
  typedef Map<const PAGNode*, CmpVFGNode*> PAGNodeToCmpVFGNodeMapTy;
72
73
  typedef Map<const SVFFunction*, VFGNodeSet > FunToVFGNodesMapTy;
73
74
 
@@ -93,6 +94,7 @@ protected:
93
94
  PAGNodeToPHIVFGNodeMapTy PAGNodeToIntraPHIVFGNodeMap; ///< map a PAGNode to its PHIVFGNode
94
95
  PAGNodeToBinaryOPVFGNodeMapTy PAGNodeToBinaryOPVFGNodeMap; ///< map a PAGNode to its BinaryOPVFGNode
95
96
  PAGNodeToUnaryOPVFGNodeMapTy PAGNodeToUnaryOPVFGNodeMap; ///< map a PAGNode to its UnaryOPVFGNode
97
+ PAGNodeToBranchVFGNodeMapTy PAGNodeToBranchVFGNodeMap; ///< map a PAGNode to its BranchVFGNode
96
98
  PAGNodeToCmpVFGNodeMapTy PAGNodeToCmpVFGNodeMap; ///< map a PAGNode to its CmpVFGNode
97
99
  PAGEdgeToStmtVFGNodeMapTy PAGEdgeToStmtVFGNodeMap; ///< map a PAGEdge to its StmtVFGNode
98
100
  FunToVFGNodesMapTy funToVFGNodesMap; ///< map a function to its VFGNodes;
@@ -218,6 +220,12 @@ public:
218
220
  assert(it != PAGNodeToUnaryOPVFGNodeMap.end() && "UnaryOPVFGNode can not be found??");
219
221
  return it->second;
220
222
  }
223
+ inline BranchVFGNode* getBranchVFGNode(const PAGNode* pagNode) const
224
+ {
225
+ PAGNodeToBranchVFGNodeMapTy::const_iterator it = PAGNodeToBranchVFGNodeMap.find(pagNode);
226
+ assert(it != PAGNodeToBranchVFGNodeMap.end() && "BranchVFGNode can not be found??");
227
+ return it->second;
228
+ }
221
229
  inline CmpVFGNode* getCmpVFGNode(const PAGNode* pagNode) const
222
230
  {
223
231
  PAGNodeToCmpVFGNodeMapTy::const_iterator it = PAGNodeToCmpVFGNodeMap.find(pagNode);
@@ -561,70 +569,63 @@ protected:
561
569
  PAGNodeToActualRetMap[ret] = sNode;
562
570
  }
563
571
  /// Add an llvm PHI VFG node
564
- inline void addIntraPHIVFGNode(const PAGNode* phiResNode, SVFIR::CopyPEList& oplist)
572
+ inline void addIntraPHIVFGNode(const PhiPE* edge)
565
573
  {
566
- IntraPHIVFGNode* sNode = new IntraPHIVFGNode(totalVFGNode++,phiResNode);
574
+ IntraPHIVFGNode* sNode = new IntraPHIVFGNode(totalVFGNode++,edge->getRes());
567
575
  u32_t pos = 0;
568
- const PAGEdge* edge = nullptr;
569
- for(SVFIR::CopyPEList::const_iterator it = oplist.begin(), eit=oplist.end(); it!=eit; ++it,++pos)
576
+ for(auto var : edge->getOpndVars())
570
577
  {
571
- edge = *it;
572
- sNode->setOpVerAndBB(pos, edge->getSrcNode(), edge->getICFGNode());
578
+ sNode->setOpVerAndBB(pos, var, edge->getICFGNode());
579
+ pos++;
573
580
  }
574
- assert(edge && "edge not found?");
575
581
  addVFGNode(sNode,edge->getICFGNode());
576
- setDef(phiResNode,sNode);
577
- PAGNodeToIntraPHIVFGNodeMap[phiResNode] = sNode;
582
+ setDef(edge->getRes(),sNode);
583
+ PAGNodeToIntraPHIVFGNodeMap[edge->getRes()] = sNode;
578
584
  }
579
585
  /// Add a Compare VFG node
580
- inline void addCmpVFGNode(const PAGNode* resNode, SVFIR::CmpPEList& oplist)
586
+ inline void addCmpVFGNode(const CmpPE* edge)
581
587
  {
582
- CmpVFGNode* sNode = new CmpVFGNode(totalVFGNode++, resNode);
588
+ CmpVFGNode* sNode = new CmpVFGNode(totalVFGNode++, edge->getRes());
583
589
  u32_t pos = 0;
584
- const PAGEdge* edge = nullptr;
585
- for(SVFIR::CmpPEList::const_iterator it = oplist.begin(), eit=oplist.end(); it!=eit; ++it,++pos)
590
+ for(auto var : edge->getOpndVars())
586
591
  {
587
- edge = *it;
588
- sNode->setOpVer(pos, edge->getSrcNode());
592
+ sNode->setOpVer(pos, var);
593
+ pos++;
589
594
  }
590
- assert(edge && "edge not found?");
591
595
  addVFGNode(sNode,edge->getICFGNode());
592
- setDef(resNode,sNode);
593
- PAGNodeToCmpVFGNodeMap[resNode] = sNode;
596
+ setDef(edge->getRes(),sNode);
597
+ PAGNodeToCmpVFGNodeMap[edge->getRes()] = sNode;
594
598
  }
595
599
  /// Add a BinaryOperator VFG node
596
- inline void addBinaryOPVFGNode(const PAGNode* resNode, SVFIR::BinaryOPList& oplist)
600
+ inline void addBinaryOPVFGNode(const BinaryOPPE* edge)
597
601
  {
598
- BinaryOPVFGNode* sNode = new BinaryOPVFGNode(totalVFGNode++, resNode);
602
+ BinaryOPVFGNode* sNode = new BinaryOPVFGNode(totalVFGNode++, edge->getRes());
599
603
  u32_t pos = 0;
600
- const PAGEdge* edge = nullptr;
601
- for(SVFIR::BinaryOPList::const_iterator it = oplist.begin(), eit=oplist.end(); it!=eit; ++it,++pos)
604
+ for(auto var : edge->getOpndVars())
602
605
  {
603
- edge = *it;
604
- sNode->setOpVer(pos, (*it)->getSrcNode());
606
+ sNode->setOpVer(pos, var);
607
+ pos++;
605
608
  }
606
-
607
- assert(edge && "edge not found?");
608
609
  addVFGNode(sNode,edge->getICFGNode());
609
- setDef(resNode,sNode);
610
- PAGNodeToBinaryOPVFGNodeMap[resNode] = sNode;
610
+ setDef(edge->getRes(),sNode);
611
+ PAGNodeToBinaryOPVFGNodeMap[edge->getRes()] = sNode;
611
612
  }
612
613
  /// Add a UnaryOperator VFG node
613
- inline void addUnaryOPVFGNode(const PAGNode* resNode, SVFIR::UnaryOPList& oplist)
614
+ inline void addUnaryOPVFGNode(const UnaryOPPE* edge)
614
615
  {
615
- UnaryOPVFGNode* sNode = new UnaryOPVFGNode(totalVFGNode++, resNode);
616
- u32_t pos = 0;
617
- const PAGEdge* edge = nullptr;
618
- for(SVFIR::UnaryOPList::const_iterator it = oplist.begin(), eit=oplist.end(); it!=eit; ++it,++pos)
619
- {
620
- edge = *it;
621
- sNode->setOpVer(pos, (*it)->getSrcNode());
622
- }
623
-
624
- assert(edge && "edge not found?");
616
+ UnaryOPVFGNode* sNode = new UnaryOPVFGNode(totalVFGNode++, edge->getRes());
617
+ sNode->setOpVer(0, edge->getOpVar());
618
+ addVFGNode(sNode,edge->getICFGNode());
619
+ setDef(edge->getRes(),sNode);
620
+ PAGNodeToUnaryOPVFGNodeMap[edge->getRes()] = sNode;
621
+ }
622
+ /// Add a BranchVFGNode
623
+ inline void addBranchVFGNode(const BranchStmt* edge)
624
+ {
625
+ BranchVFGNode* sNode = new BranchVFGNode(totalVFGNode++, edge);
625
626
  addVFGNode(sNode,edge->getICFGNode());
626
- setDef(resNode,sNode);
627
- PAGNodeToUnaryOPVFGNodeMap[resNode] = sNode;
627
+ setDef(edge->getBranchInst(),sNode);
628
+ PAGNodeToBranchVFGNodeMap[edge->getBranchInst()] = sNode;
628
629
  }
629
630
  };
630
631
 
@@ -51,7 +51,7 @@ public:
51
51
  /// Gep represents offset edge for field sensitivity
52
52
  enum VFGNodeK
53
53
  {
54
- Addr, Copy, Gep, Store, Load, Cmp, BinaryOp, UnaryOp, TPhi, TIntraPhi, TInterPhi,
54
+ Addr, Copy, Gep, Store, Load, Cmp, BinaryOp, UnaryOp, Branch, TPhi, TIntraPhi, TInterPhi,
55
55
  MPhi, MIntraPhi, MInterPhi, FRet, ARet, AParm, FParm,
56
56
  FunRet, APIN, APOUT, FPIN, FPOUT, NPtr, DummyVProp
57
57
  };
@@ -330,7 +330,7 @@ public:
330
330
  CmpVFGNode(NodeID id,const PAGNode* r): VFGNode(id,Cmp), res(r)
331
331
  {
332
332
  const CmpInst* cmp = SVFUtil::dyn_cast<CmpInst>(r->getValue());
333
- assert(cmp && "not a binary operator?");
333
+ assert(cmp && "not a compare operator?");
334
334
  }
335
335
  /// Methods for support type inquiry through isa, cast, and dyn_cast:
336
336
  //@{
@@ -473,10 +473,7 @@ public:
473
473
  /// Constructor
474
474
  UnaryOPVFGNode(NodeID id, const PAGNode *r) : VFGNode(id, UnaryOp), res(r) {
475
475
  const Value *val = r->getValue();
476
- bool unop = (SVFUtil::isa<UnaryOperator>(val)
477
- || SVFUtil::isa<BranchInst>(val)
478
- || SVFUtil::isa<SwitchInst>(val));
479
- assert(unop && "not a unary operator or a BranchInst or a SwitchInst?");
476
+ assert(SVFUtil::isa<UnaryOperator>(val) && "not a unary instruction ?");
480
477
  }
481
478
  /// Methods for support type inquiry through isa, cast, and dyn_cast:
482
479
  //@{
@@ -509,6 +506,11 @@ public:
509
506
  {
510
507
  return res;
511
508
  }
509
+ inline const PAGNode* getOpVar() const
510
+ {
511
+ assert(getOpVerNum()==1 && "UnaryNode can only have one operand!");
512
+ return getOpVer(0);
513
+ }
512
514
  inline u32_t getOpVerNum() const
513
515
  {
514
516
  return opVers.size();
@@ -526,6 +528,57 @@ public:
526
528
  virtual const std::string toString() const;
527
529
  };
528
530
 
531
+ /*
532
+ * Branch VFGNode including if/else and switch statements
533
+ */
534
+ class BranchVFGNode: public VFGNode
535
+ {
536
+ private:
537
+ BranchVFGNode(); ///< place holder
538
+ BranchVFGNode(const BranchVFGNode &); ///< place holder
539
+ void operator=(const BranchVFGNode &); ///< place holder
540
+ const BranchStmt* brstmt;
541
+ public:
542
+ /// Constructor
543
+ BranchVFGNode(NodeID id, const BranchStmt* r) : VFGNode(id, Branch), brstmt(r) {
544
+ const Value *val = r->getValue();
545
+ assert((SVFUtil::isa<BranchInst>(val) || SVFUtil::isa<SwitchInst>(val)) && "not a BranchInst or a SwitchInst?");
546
+ }
547
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
548
+ //@{
549
+ static inline bool classof(const BranchVFGNode *)
550
+ {
551
+ return true;
552
+ }
553
+ static inline bool classof(const VFGNode *node)
554
+ {
555
+ return node->getNodeKind() == Branch;
556
+ }
557
+ static inline bool classof(const GenericVFGNodeTy *node)
558
+ {
559
+ return node->getNodeKind() == Branch;
560
+ }
561
+ //@}
562
+
563
+ /// Return the branch statement
564
+ const BranchStmt* getBranchStmt() const{
565
+ return brstmt;
566
+ }
567
+ /// Successors of this branch statement
568
+ ///@{
569
+ u32_t getNumSuccessors() const{
570
+ return brstmt->getNumSuccessors();
571
+ }
572
+ const std::vector<const ICFGNode*>& getSuccessors() const{
573
+ return brstmt->getSuccessors();
574
+ }
575
+ const ICFGNode* getSuccessor (u32_t i) const{
576
+ return brstmt->getSuccessor(i);
577
+ }
578
+ ///@}
579
+ virtual const std::string toString() const override;
580
+ };
581
+
529
582
  /*!
530
583
  * VFGNode for Gep
531
584
  */
@@ -1091,7 +1144,7 @@ public:
1091
1144
  return node->isPointer();
1092
1145
  }
1093
1146
  /// Return corresponding PAGNode
1094
- const PAGNode* getGNode() const
1147
+ const PAGNode* getPAGNode() const
1095
1148
  {
1096
1149
  return node;
1097
1150
  }