svf-tools 1.0.645 → 1.0.646
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.646",
|
|
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": {
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
//===- CFBasicBlockG.h ----------------------------------------------------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-2018> <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
|
+
* CFBasicBlockG.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: 24 Dec. 2022
|
|
27
|
+
* Author: Xiao, Jiawei
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef SVF_CFBASICBLOCKG_H
|
|
31
|
+
#define SVF_CFBASICBLOCKG_H
|
|
32
|
+
#include "Util/SVFUtil.h"
|
|
33
|
+
#include "Graphs/ICFGNode.h"
|
|
34
|
+
#include "Graphs/GenericGraph.h"
|
|
35
|
+
|
|
36
|
+
namespace SVF
|
|
37
|
+
{
|
|
38
|
+
class CFBasicBlockNode;
|
|
39
|
+
class SVFIR;
|
|
40
|
+
|
|
41
|
+
typedef GenericEdge<CFBasicBlockNode> GenericCFBasicBlockEdgeTy;
|
|
42
|
+
|
|
43
|
+
class CFBasicBlockEdge : public GenericCFBasicBlockEdgeTy
|
|
44
|
+
{
|
|
45
|
+
public:
|
|
46
|
+
CFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst) : GenericCFBasicBlockEdgeTy(src, dst, 0) {}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
friend std::ostream &operator<<(std::ostream &o, const CFBasicBlockEdge &edge)
|
|
50
|
+
{
|
|
51
|
+
o << edge.toString();
|
|
52
|
+
return o;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
virtual const std::string toString() const
|
|
56
|
+
{
|
|
57
|
+
return std::to_string(getSrcID()) + " --> " + std::to_string(getDstID());
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
typedef GenericNode<CFBasicBlockNode, CFBasicBlockEdge> GenericCFBasicBlockNodeTy;
|
|
62
|
+
|
|
63
|
+
class CFBasicBlockNode : public GenericCFBasicBlockNodeTy
|
|
64
|
+
{
|
|
65
|
+
private:
|
|
66
|
+
const SVFBasicBlock *_svfBasicBlock; /// Every CFBasicBlockNode holds a SVFBasicBlock
|
|
67
|
+
std::vector<const ICFGNode *> _icfgNodes; /// Every CBFGNode holds a vector of ICFGNodes
|
|
68
|
+
|
|
69
|
+
public:
|
|
70
|
+
CFBasicBlockNode(u32_t id, const SVFBasicBlock *svfBasicBlock);
|
|
71
|
+
|
|
72
|
+
friend std::ostream &operator<<(std::ostream &o, const CFBasicBlockNode &node)
|
|
73
|
+
{
|
|
74
|
+
o << node.toString();
|
|
75
|
+
return o;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
virtual const std::string toString() const;
|
|
79
|
+
|
|
80
|
+
inline std::string getName() const;
|
|
81
|
+
|
|
82
|
+
inline const SVFBasicBlock *getSVFBasicBlock() const;
|
|
83
|
+
|
|
84
|
+
inline const SVFFunction *getFunction() const;
|
|
85
|
+
|
|
86
|
+
inline std::vector<const ICFGNode *>::const_iterator begin() const
|
|
87
|
+
{
|
|
88
|
+
return _icfgNodes.cbegin();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
inline std::vector<const ICFGNode *>::const_iterator end() const
|
|
92
|
+
{
|
|
93
|
+
return _icfgNodes.cend();
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
typedef GenericGraph<CFBasicBlockNode, CFBasicBlockEdge> GenericCFBasicBlockGTy;
|
|
98
|
+
|
|
99
|
+
class CFBasicBlockGraph : public GenericCFBasicBlockGTy
|
|
100
|
+
{
|
|
101
|
+
friend class CFBasicBlockGBuilder;
|
|
102
|
+
|
|
103
|
+
public:
|
|
104
|
+
typedef Map<const SVFBasicBlock *, CFBasicBlockNode *> SVFBasicBlockToCFBasicBlockNodeMap;
|
|
105
|
+
|
|
106
|
+
private:
|
|
107
|
+
SVFBasicBlockToCFBasicBlockNodeMap _bbToNode;
|
|
108
|
+
const SVFFunction *_svfFunction;
|
|
109
|
+
u32_t _totalCFBasicBlockNode{0};
|
|
110
|
+
u32_t _totalCFBasicBlockEdge{0};
|
|
111
|
+
|
|
112
|
+
public:
|
|
113
|
+
|
|
114
|
+
CFBasicBlockGraph(const SVFFunction *svfFunction) : _svfFunction(svfFunction)
|
|
115
|
+
{
|
|
116
|
+
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
~CFBasicBlockGraph() override = default;
|
|
120
|
+
|
|
121
|
+
/// Dump graph into dot file
|
|
122
|
+
void dump(const std::string &filename)
|
|
123
|
+
{
|
|
124
|
+
GraphPrinter::WriteGraphToFile(SVFUtil::outs(), filename, this);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
inline CFBasicBlockNode *getCFBasicBlockNode(u32_t id) const;
|
|
128
|
+
|
|
129
|
+
inline CFBasicBlockNode *getCFBasicBlockNode(const SVFBasicBlock *bb) const;
|
|
130
|
+
|
|
131
|
+
inline bool hasCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst);
|
|
132
|
+
|
|
133
|
+
CFBasicBlockEdge* getCFBasicBlockEdge(const CFBasicBlockNode *src, const CFBasicBlockNode *dst);
|
|
134
|
+
|
|
135
|
+
CFBasicBlockEdge* getCFBasicBlockEdge(const SVFBasicBlock *src, const SVFBasicBlock *dst);
|
|
136
|
+
|
|
137
|
+
private:
|
|
138
|
+
|
|
139
|
+
/// Add a CFBasicBlockNode
|
|
140
|
+
inline const CFBasicBlockNode* getOrAddCFBasicBlockNode(const SVFBasicBlock *bb);
|
|
141
|
+
|
|
142
|
+
inline const CFBasicBlockEdge *getOrAddCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst);
|
|
143
|
+
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
class CFBasicBlockGBuilder
|
|
147
|
+
{
|
|
148
|
+
|
|
149
|
+
private:
|
|
150
|
+
CFBasicBlockGraph* _CFBasicBlockG;
|
|
151
|
+
|
|
152
|
+
public:
|
|
153
|
+
CFBasicBlockGBuilder(const SVFFunction *func) : _CFBasicBlockG(new CFBasicBlockGraph(func)) {}
|
|
154
|
+
|
|
155
|
+
void build();
|
|
156
|
+
|
|
157
|
+
inline CFBasicBlockGraph* getCFBasicBlockGraph()
|
|
158
|
+
{
|
|
159
|
+
return _CFBasicBlockG;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
namespace SVF
|
|
166
|
+
{
|
|
167
|
+
/* !
|
|
168
|
+
* GenericGraphTraits specializations for generic graph algorithms.
|
|
169
|
+
* Provide graph traits for traversing from a constraint node using standard graph ICFGTraversals.
|
|
170
|
+
*/
|
|
171
|
+
template<>
|
|
172
|
+
struct GenericGraphTraits<SVF::CFBasicBlockNode *>
|
|
173
|
+
: public GenericGraphTraits<SVF::GenericNode<SVF::CFBasicBlockNode, SVF::CFBasicBlockEdge> *>
|
|
174
|
+
{
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/// Inverse GenericGraphTraits specializations for call graph node, it is used for inverse ICFGTraversal.
|
|
178
|
+
template<>
|
|
179
|
+
struct GenericGraphTraits<Inverse< SVF::CFBasicBlockNode *> > : public GenericGraphTraits<
|
|
180
|
+
Inverse<SVF::GenericNode<SVF::CFBasicBlockNode, SVF::CFBasicBlockEdge> *> >
|
|
181
|
+
{
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
template<>
|
|
185
|
+
struct GenericGraphTraits<SVF::CFBasicBlockGraph *>
|
|
186
|
+
: public GenericGraphTraits<SVF::GenericGraph<SVF::CFBasicBlockNode, SVF::CFBasicBlockEdge> *>
|
|
187
|
+
{
|
|
188
|
+
typedef SVF::CFBasicBlockNode *NodeRef;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
template<>
|
|
192
|
+
struct DOTGraphTraits<SVF::CFBasicBlockGraph *> : public DOTGraphTraits<SVF::SVFIR *>
|
|
193
|
+
{
|
|
194
|
+
|
|
195
|
+
typedef SVF::CFBasicBlockNode NodeType;
|
|
196
|
+
|
|
197
|
+
DOTGraphTraits(bool isSimple = false) :
|
|
198
|
+
DOTGraphTraits<SVF::SVFIR *>(isSimple)
|
|
199
|
+
{
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/// Return name of the graph
|
|
203
|
+
static std::string getGraphName(SVF::CFBasicBlockGraph *)
|
|
204
|
+
{
|
|
205
|
+
return "CFBasicBlockGraph";
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
std::string getNodeLabel(NodeType *node, SVF::CFBasicBlockGraph *graph)
|
|
209
|
+
{
|
|
210
|
+
return getSimpleNodeLabel(node, graph);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/// Return the label of an ICFG node
|
|
214
|
+
static std::string getSimpleNodeLabel(NodeType *node, SVF::CFBasicBlockGraph *)
|
|
215
|
+
{
|
|
216
|
+
std::string str;
|
|
217
|
+
std::stringstream rawstr(str);
|
|
218
|
+
rawstr << "NodeID: " << node->getId() << "\n";
|
|
219
|
+
rawstr << node->toString();
|
|
220
|
+
|
|
221
|
+
return rawstr.str();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
static std::string getNodeAttributes(NodeType *node, SVF::CFBasicBlockGraph *)
|
|
225
|
+
{
|
|
226
|
+
std::string str;
|
|
227
|
+
std::stringstream rawstr(str);
|
|
228
|
+
rawstr << "color=black";
|
|
229
|
+
return rawstr.str();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
template<class EdgeIter>
|
|
233
|
+
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVF::CFBasicBlockGraph *)
|
|
234
|
+
{
|
|
235
|
+
return "style=solid";
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
template<class EdgeIter>
|
|
239
|
+
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
|
|
240
|
+
{
|
|
241
|
+
return "";
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
} // End namespace SVF
|
|
246
|
+
#endif //SVF_CFBASICBLOCKG_H
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
//===- CFBasicBlockG.cpp ----------------------------------------------------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-2018> <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
|
+
* CFBasicBlockG.cpp
|
|
25
|
+
*
|
|
26
|
+
* Created on: 24 Dec. 2022
|
|
27
|
+
* Author: Xiao, Jiawei
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#include "Graphs/CFBasicBlockG.h"
|
|
31
|
+
#include "SVFIR/SVFIR.h"
|
|
32
|
+
|
|
33
|
+
namespace SVF
|
|
34
|
+
{
|
|
35
|
+
CFBasicBlockNode::CFBasicBlockNode(u32_t id, const SVFBasicBlock *svfBasicBlock) : GenericCFBasicBlockNodeTy(id, 0),
|
|
36
|
+
_svfBasicBlock(svfBasicBlock)
|
|
37
|
+
{
|
|
38
|
+
for (auto it = svfBasicBlock->begin(); it != svfBasicBlock->end(); ++it)
|
|
39
|
+
{
|
|
40
|
+
const SVFInstruction *ins = *it;
|
|
41
|
+
ICFGNode *icfgNode = PAG::getPAG()->getICFG()->getICFGNode(ins);
|
|
42
|
+
_icfgNodes.push_back(icfgNode);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const std::string CFBasicBlockNode::toString() const
|
|
47
|
+
{
|
|
48
|
+
std::string rawStr;
|
|
49
|
+
std::stringstream stringstream(rawStr);
|
|
50
|
+
stringstream << "Block Name: " << _svfBasicBlock->getName() << "\n";
|
|
51
|
+
for (const auto &icfgNode: _icfgNodes)
|
|
52
|
+
{
|
|
53
|
+
stringstream << icfgNode->toString() << "\n";
|
|
54
|
+
}
|
|
55
|
+
return stringstream.str();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
std::string CFBasicBlockNode::getName() const
|
|
59
|
+
{
|
|
60
|
+
return _svfBasicBlock->getName();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const SVFBasicBlock* CFBasicBlockNode::getSVFBasicBlock() const
|
|
64
|
+
{
|
|
65
|
+
return _svfBasicBlock;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const SVFFunction* CFBasicBlockNode::getFunction() const
|
|
69
|
+
{
|
|
70
|
+
return _svfBasicBlock->getFunction();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
bool CFBasicBlockGraph::hasCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst)
|
|
74
|
+
{
|
|
75
|
+
CFBasicBlockEdge edge(src, dst);
|
|
76
|
+
CFBasicBlockEdge *outEdge = src->hasOutgoingEdge(&edge);
|
|
77
|
+
CFBasicBlockEdge *inEdge = dst->hasIncomingEdge(&edge);
|
|
78
|
+
if (outEdge && inEdge)
|
|
79
|
+
{
|
|
80
|
+
assert(outEdge == inEdge && "edges not match");
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
else
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
CFBasicBlockNode* CFBasicBlockGraph::getCFBasicBlockNode(u32_t id) const
|
|
88
|
+
{
|
|
89
|
+
if (!hasGNode(id)) return nullptr;
|
|
90
|
+
return getGNode(id);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
CFBasicBlockNode* CFBasicBlockGraph::getCFBasicBlockNode(const SVFBasicBlock *bb) const
|
|
94
|
+
{
|
|
95
|
+
auto it = _bbToNode.find(bb);
|
|
96
|
+
if (it == _bbToNode.end()) return nullptr;
|
|
97
|
+
return it->second;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
CFBasicBlockEdge* CFBasicBlockGraph::getCFBasicBlockEdge(const SVFBasicBlock *src, const SVFBasicBlock *dst)
|
|
101
|
+
{
|
|
102
|
+
return getCFBasicBlockEdge(getCFBasicBlockNode(src), getCFBasicBlockNode(dst));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
CFBasicBlockEdge* CFBasicBlockGraph::getCFBasicBlockEdge(const CFBasicBlockNode *src, const CFBasicBlockNode *dst)
|
|
106
|
+
{
|
|
107
|
+
CFBasicBlockEdge *edge = nullptr;
|
|
108
|
+
size_t counter = 0;
|
|
109
|
+
for (auto iter = src->OutEdgeBegin();
|
|
110
|
+
iter != src->OutEdgeEnd(); ++iter)
|
|
111
|
+
{
|
|
112
|
+
if ((*iter)->getDstID() == dst->getId())
|
|
113
|
+
{
|
|
114
|
+
counter++;
|
|
115
|
+
edge = (*iter);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
assert(counter <= 1 && "there's more than one edge between two nodes");
|
|
119
|
+
return edge;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const CFBasicBlockNode* CFBasicBlockGraph::getOrAddCFBasicBlockNode(const SVFBasicBlock *bb)
|
|
123
|
+
{
|
|
124
|
+
auto it = _bbToNode.find(bb);
|
|
125
|
+
if (it != _bbToNode.end()) return it->second;
|
|
126
|
+
CFBasicBlockNode *node = new CFBasicBlockNode(_totalCFBasicBlockNode++, bb);
|
|
127
|
+
_bbToNode[bb] = node;
|
|
128
|
+
addGNode(node->getId(), node);
|
|
129
|
+
return node;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const CFBasicBlockEdge* CFBasicBlockGraph::getOrAddCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst)
|
|
133
|
+
{
|
|
134
|
+
if (const CFBasicBlockEdge *edge = getCFBasicBlockEdge(src, dst)) return edge;
|
|
135
|
+
CFBasicBlockEdge *edge = new CFBasicBlockEdge(src, dst);
|
|
136
|
+
bool added1 = edge->getDstNode()->addIncomingEdge(edge);
|
|
137
|
+
bool added2 = edge->getSrcNode()->addOutgoingEdge(edge);
|
|
138
|
+
assert(added1 && added2 && "edge not added??");
|
|
139
|
+
_totalCFBasicBlockEdge++;
|
|
140
|
+
return edge;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
void CFBasicBlockGBuilder::build()
|
|
144
|
+
{
|
|
145
|
+
for (const auto &bb: *_CFBasicBlockG->_svfFunction)
|
|
146
|
+
{
|
|
147
|
+
_CFBasicBlockG->getOrAddCFBasicBlockNode(bb);
|
|
148
|
+
}
|
|
149
|
+
for (const auto &bb: *_CFBasicBlockG->_svfFunction)
|
|
150
|
+
{
|
|
151
|
+
for (const auto &succ: bb->getSuccessors())
|
|
152
|
+
{
|
|
153
|
+
_CFBasicBlockG->getOrAddCFBasicBlockEdge(_CFBasicBlockG->getCFBasicBlockNode(bb),
|
|
154
|
+
_CFBasicBlockG->getCFBasicBlockNode(succ));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|