svf-lib 1.0.2681 → 1.0.2682
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/SVF-linux-aarch64/bin/mta +0 -0
- package/SVF-linux-aarch64/include/AE/Core/NumericValue.h +1 -1
- package/SVF-linux-aarch64/include/Graphs/CDG.h +1 -1
- package/SVF-linux-aarch64/include/Graphs/CallGraph.h +34 -3
- package/SVF-linux-aarch64/include/Graphs/ICFG.h +6 -0
- package/SVF-linux-aarch64/include/Graphs/SVFG.h +6 -0
- package/SVF-linux-aarch64/include/Graphs/SlicedGraphs.h +119 -84
- package/SVF-linux-aarch64/include/Graphs/ThreadCallGraph.h +37 -0
- package/SVF-linux-aarch64/include/Graphs/VFG.h +1 -1
- package/SVF-linux-aarch64/include/MTA/FSMPTA.h +50 -34
- package/SVF-linux-aarch64/include/MTA/LockAnalysis.h +95 -55
- package/SVF-linux-aarch64/include/MTA/MHP.h +65 -24
- package/SVF-linux-aarch64/include/MTA/MTA.h +99 -51
- package/SVF-linux-aarch64/include/MTA/MTASVFGBuilder.h +115 -50
- package/SVF-linux-aarch64/include/MTA/MTASlicer.h +73 -79
- package/SVF-linux-aarch64/include/MTA/MTAStat.h +54 -6
- package/SVF-linux-aarch64/include/MTA/TCT.h +13 -22
- package/SVF-linux-aarch64/include/SVF-LLVM/GEPTypeBridgeIterator.h +2 -2
- package/SVF-linux-aarch64/include/SVF-LLVM/ObjTypeInference.h +1 -1
- package/SVF-linux-aarch64/include/Util/Options.h +2 -4
- package/SVF-linux-aarch64/include/Util/SparseBitVector.h +2 -2
- package/SVF-linux-aarch64/lib/libSvfCore.so.3.4 +0 -0
- package/SVF-linux-aarch64/lib/libSvfLLVM.so.3.4 +0 -0
- package/package.json +1 -1
|
Binary file
|
|
@@ -503,6 +503,11 @@ template<> struct GenericGraphTraits<SVF::CallGraph*> : public GenericGraphTrait
|
|
|
503
503
|
{
|
|
504
504
|
typedef SVF::CallGraphNode*NodeRef;
|
|
505
505
|
|
|
506
|
+
static const SVF::CallGraphNode* getRawNode(const SVF::CallGraphNode* n)
|
|
507
|
+
{
|
|
508
|
+
return n;
|
|
509
|
+
}
|
|
510
|
+
|
|
506
511
|
// Graph-intrinsic queries shared with the sliced-view specialisation
|
|
507
512
|
// (GenericGraphTraits<const SlicedThreadCallGraphView*>).
|
|
508
513
|
//@{
|
|
@@ -514,10 +519,36 @@ template<> struct GenericGraphTraits<SVF::CallGraph*> : public GenericGraphTrait
|
|
|
514
519
|
for (SVF::CallGraphEdge* e : n->getInEdges())
|
|
515
520
|
out.push_back(e);
|
|
516
521
|
}
|
|
517
|
-
|
|
518
|
-
|
|
522
|
+
static void getOutEdges(const SVF::CallGraph*, const SVF::CallGraphNode* n,
|
|
523
|
+
std::vector<const SVF::CallGraphEdge*>& out)
|
|
524
|
+
{
|
|
525
|
+
out.clear();
|
|
526
|
+
for (SVF::CallGraphEdge* e : n->getOutEdges())
|
|
527
|
+
out.push_back(e);
|
|
528
|
+
}
|
|
529
|
+
static void getDirectCalls(const SVF::CallGraph*, const SVF::CallGraphEdge* e,
|
|
530
|
+
std::vector<const SVF::CallICFGNode*>& out)
|
|
531
|
+
{
|
|
532
|
+
out.assign(e->getDirectCalls().begin(), e->getDirectCalls().end());
|
|
533
|
+
}
|
|
534
|
+
static void getIndirectCalls(const SVF::CallGraph*, const SVF::CallGraphEdge* e,
|
|
535
|
+
std::vector<const SVF::CallICFGNode*>& out)
|
|
536
|
+
{
|
|
537
|
+
out.assign(e->getIndirectCalls().begin(), e->getIndirectCalls().end());
|
|
538
|
+
}
|
|
539
|
+
static bool containsCallSite(const SVF::CallGraph*,
|
|
540
|
+
const SVF::CallGraphEdge* e,
|
|
541
|
+
const SVF::CallICFGNode* callSite)
|
|
542
|
+
{
|
|
543
|
+
return e->getDirectCalls().count(callSite) ||
|
|
544
|
+
e->getIndirectCalls().count(callSite);
|
|
545
|
+
}
|
|
546
|
+
static void getCallees(SVF::CallGraph* g,
|
|
547
|
+
const SVF::CallICFGNode* callSite,
|
|
548
|
+
SVF::CallGraph::FunctionSet& callees)
|
|
519
549
|
{
|
|
520
|
-
|
|
550
|
+
callees.clear();
|
|
551
|
+
g->getCallees(callSite, callees);
|
|
521
552
|
}
|
|
522
553
|
//@}
|
|
523
554
|
};
|
|
@@ -309,6 +309,12 @@ template<> struct GenericGraphTraits<SVF::ICFG*> : public GenericGraphTraits<SVF
|
|
|
309
309
|
{
|
|
310
310
|
return fun->getEntryBlock()->front();
|
|
311
311
|
}
|
|
312
|
+
/// Exit node of fun under the whole ICFG.
|
|
313
|
+
static const SVF::ICFGNode* getFunExit(SVF::ICFG* graph,
|
|
314
|
+
const SVF::FunObjVar* fun)
|
|
315
|
+
{
|
|
316
|
+
return graph->getFunExitICFGNode(fun);
|
|
317
|
+
}
|
|
312
318
|
/// Nodes of fun contained in this graph (whole ICFG: all of them).
|
|
313
319
|
static void getFunICFGNodes(SVF::ICFG*, const SVF::FunObjVar* fun,
|
|
314
320
|
std::vector<const SVF::ICFGNode*>& out)
|
|
@@ -500,6 +500,7 @@ namespace SVF
|
|
|
500
500
|
template<> struct GenericGraphTraits<SVF::SVFG*> : public GenericGraphTraits<SVF::GenericGraph<SVF::SVFGNode,SVF::SVFGEdge>* >
|
|
501
501
|
{
|
|
502
502
|
typedef SVF::SVFGNode *NodeRef;
|
|
503
|
+
static constexpr bool isFilteredGraph = false;
|
|
503
504
|
|
|
504
505
|
/// Whether n belongs to this graph (the whole SVFG contains every node).
|
|
505
506
|
/// Mirrored by GenericGraphTraits<const SlicedSVFGView*>, so a solver
|
|
@@ -508,6 +509,11 @@ template<> struct GenericGraphTraits<SVF::SVFG*> : public GenericGraphTraits<SVF
|
|
|
508
509
|
{
|
|
509
510
|
return true;
|
|
510
511
|
}
|
|
512
|
+
|
|
513
|
+
static bool containsEdge(SVF::SVFG*, const SVF::SVFGEdge*)
|
|
514
|
+
{
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
511
517
|
};
|
|
512
518
|
|
|
513
519
|
} // End namespace llvm
|
|
@@ -24,10 +24,6 @@
|
|
|
24
24
|
* SlicedGraphs.h
|
|
25
25
|
*
|
|
26
26
|
* Author: Jiawei Yang
|
|
27
|
-
*
|
|
28
|
-
* General non-owning sliced views of the ICFG, PAG, and (Thread)CallGraph, and
|
|
29
|
-
* their GenericGraphTraits specialisations, so a slice works with SVF's generic
|
|
30
|
-
* graph algorithms and GraphWriter.
|
|
31
27
|
*/
|
|
32
28
|
|
|
33
29
|
#ifndef GRAPHS_SLICEDGRAPHS_H
|
|
@@ -45,13 +41,9 @@
|
|
|
45
41
|
#include "SVFIR/SVFStatements.h"
|
|
46
42
|
#include "SVFIR/SVFVariables.h"
|
|
47
43
|
#include <cstddef>
|
|
48
|
-
#include <fstream>
|
|
49
44
|
#include <iterator>
|
|
50
45
|
#include <memory>
|
|
51
|
-
#include <set>
|
|
52
46
|
#include <string>
|
|
53
|
-
#include <unordered_map>
|
|
54
|
-
#include <unordered_set>
|
|
55
47
|
#include <vector>
|
|
56
48
|
#include <utility>
|
|
57
49
|
|
|
@@ -66,14 +58,9 @@ namespace SVF
|
|
|
66
58
|
class SlicedICFGView
|
|
67
59
|
{
|
|
68
60
|
public:
|
|
69
|
-
/// Build
|
|
70
|
-
// buildBridged=false skips bridged-edge construction for views whose control
|
|
71
|
-
// flow is never walked (e.g. the FSPTA view, used only for isKeptNode).
|
|
61
|
+
/// Build an ICFG view from its explicit node membership.
|
|
72
62
|
SlicedICFGView(ICFG* icfg,
|
|
73
|
-
|
|
74
|
-
const OrderedSet<const ICFGNode*>& keepNodes,
|
|
75
|
-
const OrderedSet<const FunObjVar*>& keptFunctions,
|
|
76
|
-
bool buildBridged = true);
|
|
63
|
+
const OrderedSet<const ICFGNode*>& keepNodes);
|
|
77
64
|
|
|
78
65
|
/// Get successor nodes (including bridged edges)
|
|
79
66
|
void getSuccNodes(const ICFGNode* node, std::vector<const ICFGNode*>& out) const;
|
|
@@ -84,10 +71,12 @@ public:
|
|
|
84
71
|
/// Check if a node is in the sliced view
|
|
85
72
|
bool isKeptNode(const ICFGNode* node) const;
|
|
86
73
|
|
|
87
|
-
/// First kept node of fun's entry
|
|
88
|
-
/// kept node of the entry block, else the original entry).
|
|
74
|
+
/// First kept node of fun's entry, or null when fun is outside the view.
|
|
89
75
|
const ICFGNode* getFunEntry(const FunObjVar* fun) const;
|
|
90
76
|
|
|
77
|
+
/// Kept synthetic exit node of fun, or null when fun is outside the view.
|
|
78
|
+
const ICFGNode* getFunExit(const FunObjVar* fun) const;
|
|
79
|
+
|
|
91
80
|
/// Kept ICFG nodes of fun.
|
|
92
81
|
void getFunICFGNodes(const FunObjVar* fun, std::vector<const ICFGNode*>& out) const;
|
|
93
82
|
|
|
@@ -122,16 +111,18 @@ public:
|
|
|
122
111
|
private:
|
|
123
112
|
ICFG* icfg;
|
|
124
113
|
OrderedSet<const ICFGNode*> keptNodes;
|
|
125
|
-
OrderedSet<const ICFGEdge*> keptEdges;
|
|
126
114
|
Map<const ICFGNode*, OrderedSet<const ICFGNode*>> bridgedEdges;
|
|
127
115
|
// Reverse of bridgedEdges (dst -> srcs), so getPredNodes is O(preds) instead
|
|
128
116
|
// of scanning every bridged edge.
|
|
129
117
|
Map<const ICFGNode*, OrderedSet<const ICFGNode*>> bridgedPreds;
|
|
130
118
|
Set<const ICFGNode*> keptNodesSet; // For fast lookup
|
|
131
119
|
|
|
132
|
-
void buildICFGSets(const OrderedSet<const ICFGNode*>& keepNodes
|
|
133
|
-
const OrderedSet<const FunObjVar*>& keptFunctions);
|
|
120
|
+
void buildICFGSets(const OrderedSet<const ICFGNode*>& keepNodes);
|
|
134
121
|
void buildBridgedEdges();
|
|
122
|
+
static void getLocalSuccessors(
|
|
123
|
+
const ICFGNode* node,
|
|
124
|
+
const Map<const ICFGNode*, const ICFGNode*>& callsiteReturnNodes,
|
|
125
|
+
std::vector<const ICFGNode*>& successors);
|
|
135
126
|
};
|
|
136
127
|
|
|
137
128
|
//===----------------------------------------------------------------------===//
|
|
@@ -187,7 +178,7 @@ class SlicedThreadCallGraphView
|
|
|
187
178
|
public:
|
|
188
179
|
SlicedThreadCallGraphView(ThreadCallGraph* tcg,
|
|
189
180
|
const OrderedSet<const FunObjVar*>& keptFunctions,
|
|
190
|
-
const OrderedSet<const ICFGNode*>& extendedKeptNodes
|
|
181
|
+
const OrderedSet<const ICFGNode*>& extendedKeptNodes);
|
|
191
182
|
|
|
192
183
|
/// Get out edges of a node (only returns kept edges and target nodes)
|
|
193
184
|
void getOutEdgesOf(const CallGraphNode* node, std::vector<const CallGraphEdge*>& out) const;
|
|
@@ -195,6 +186,27 @@ public:
|
|
|
195
186
|
/// Get in edges of a node (only returns kept edges and source nodes)
|
|
196
187
|
void getInEdgesOf(const CallGraphNode* node, std::vector<const CallGraphEdge*>& out) const;
|
|
197
188
|
|
|
189
|
+
/// Retained callsites carried by an aggregated call-graph edge.
|
|
190
|
+
void getDirectCallsOf(const CallGraphEdge* edge,
|
|
191
|
+
std::vector<const CallICFGNode*>& out) const;
|
|
192
|
+
void getIndirectCallsOf(const CallGraphEdge* edge,
|
|
193
|
+
std::vector<const CallICFGNode*>& out) const;
|
|
194
|
+
|
|
195
|
+
/// Whether this precise callsite-to-callee relation is retained.
|
|
196
|
+
bool containsCallSite(const CallGraphEdge* edge,
|
|
197
|
+
const CallICFGNode* callSite) const;
|
|
198
|
+
|
|
199
|
+
/// Retained callees of a callsite.
|
|
200
|
+
void getCalleesOf(const CallICFGNode* callSite,
|
|
201
|
+
CallGraph::FunctionSet& callees) const;
|
|
202
|
+
|
|
203
|
+
/// Retained thread relations indexed by their fork/join callsite. Join
|
|
204
|
+
/// relations are deliberately separate from normal CallGraph adjacency.
|
|
205
|
+
void getForkEdgesOf(const CallICFGNode* callSite,
|
|
206
|
+
std::vector<const CallGraphEdge*>& out) const;
|
|
207
|
+
void getJoinEdgesOf(const CallICFGNode* callSite,
|
|
208
|
+
std::vector<const CallGraphEdge*>& out) const;
|
|
209
|
+
|
|
198
210
|
/// Check if a node is in the sliced view
|
|
199
211
|
bool isKeptNode(const CallGraphNode* node) const;
|
|
200
212
|
|
|
@@ -209,17 +221,11 @@ public:
|
|
|
209
221
|
return keptFunctionsSet;
|
|
210
222
|
}
|
|
211
223
|
|
|
212
|
-
/// Get all kept edges
|
|
213
|
-
inline const CallGraph::CallGraphEdgeSet& getKeptEdges() const
|
|
214
|
-
{
|
|
215
|
-
return keptEdges;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
224
|
/// Canonical edge membership: keptEdges excludes edges whose call site was
|
|
219
225
|
/// pruned, so endpoint checks alone are not enough (queries/traits use this).
|
|
220
226
|
inline bool isKeptEdge(const CallGraphEdge* e) const
|
|
221
227
|
{
|
|
222
|
-
return keptEdges.find(
|
|
228
|
+
return keptEdges.find(e) != keptEdges.end();
|
|
223
229
|
}
|
|
224
230
|
|
|
225
231
|
/// Indirect call sites that lost all targets after filtering
|
|
@@ -231,14 +237,9 @@ public:
|
|
|
231
237
|
/// Dump sliced ThreadCallGraph to dot file
|
|
232
238
|
void dump(const std::string& filename) const;
|
|
233
239
|
|
|
234
|
-
///
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return tcg;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/// Get original CallGraph (ThreadCallGraph inherits from CallGraph)
|
|
241
|
-
inline CallGraph* getOriginalCallGraph() const
|
|
240
|
+
/// Backing graph access for the graph-traits implementation only. Analysis
|
|
241
|
+
/// traversal must use this view's filtered methods above.
|
|
242
|
+
inline CallGraph* getBackingCallGraph() const
|
|
242
243
|
{
|
|
243
244
|
return tcg;
|
|
244
245
|
}
|
|
@@ -246,7 +247,9 @@ public:
|
|
|
246
247
|
private:
|
|
247
248
|
ThreadCallGraph* tcg;
|
|
248
249
|
OrderedSet<const CallGraphNode*> keptNodes;
|
|
249
|
-
|
|
250
|
+
Set<const CallGraphEdge*> keptEdges;
|
|
251
|
+
Map<const CallGraphEdge*, CallGraphEdge::CallInstSet> keptDirectCalls;
|
|
252
|
+
Map<const CallGraphEdge*, CallGraphEdge::CallInstSet> keptIndirectCalls;
|
|
250
253
|
Set<const FunObjVar*> keptFunctionsSet; // For fast lookup
|
|
251
254
|
Set<const CallICFGNode*> indirectSitesWithEmptyTargets;
|
|
252
255
|
OrderedSet<const ICFGNode*> extendedKeptNodes; // For checking if call sites are kept
|
|
@@ -256,21 +259,16 @@ private:
|
|
|
256
259
|
};
|
|
257
260
|
|
|
258
261
|
//===----------------------------------------------------------------------===//
|
|
259
|
-
// SlicedSVFGView - non-owning
|
|
260
|
-
//
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
// Deliberately NO bridge edges: bridging removed SVFG nodes could fabricate
|
|
264
|
-
// value-flow paths that do not exist in the original graph. Removed nodes act
|
|
265
|
-
// as propagation barriers (matching the sliced FSAM solve).
|
|
262
|
+
// SlicedSVFGView - non-owning exact node-induced view of an SVFG.
|
|
263
|
+
// Membership is supplied as an explicit node-ID set; an edge is visible iff
|
|
264
|
+
// both endpoints are retained. There are deliberately no bridge edges, since
|
|
265
|
+
// bridging would fabricate value-flow paths.
|
|
266
266
|
//===----------------------------------------------------------------------===//
|
|
267
267
|
class SlicedSVFGView
|
|
268
268
|
{
|
|
269
269
|
public:
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
explicit SlicedSVFGView(const SlicedICFGView* icfgView, const SVFG* svfg = nullptr)
|
|
273
|
-
: icfgView(icfgView), svfg(svfg) {}
|
|
270
|
+
SlicedSVFGView(const SVFG* svfg, const NodeBS& retainedNodeIds)
|
|
271
|
+
: svfg(svfg), retainedNodeIds(retainedNodeIds) {}
|
|
274
272
|
|
|
275
273
|
/// Whether the node is retained (see the class comment for the rule).
|
|
276
274
|
bool isKeptNode(const SVFGNode* n) const;
|
|
@@ -281,26 +279,18 @@ public:
|
|
|
281
279
|
return isKeptNode(e->getSrcNode()) && isKeptNode(e->getDstNode());
|
|
282
280
|
}
|
|
283
281
|
|
|
284
|
-
inline const SlicedICFGView* getICFGView() const
|
|
285
|
-
{
|
|
286
|
-
return icfgView;
|
|
287
|
-
}
|
|
288
282
|
inline const SVFG* getSVFG() const
|
|
289
283
|
{
|
|
290
284
|
return svfg;
|
|
291
285
|
}
|
|
292
|
-
|
|
293
|
-
inline void setSVFG(const SVFG* g)
|
|
294
|
-
{
|
|
295
|
-
svfg = g;
|
|
296
|
-
}
|
|
286
|
+
size_t getKeptNodeCount() const;
|
|
297
287
|
|
|
298
288
|
/// Dump the sliced SVFG (retained nodes/edges only) via GraphWriter.
|
|
299
289
|
void dump(const std::string& filename) const;
|
|
300
290
|
|
|
301
291
|
private:
|
|
302
|
-
const
|
|
303
|
-
|
|
292
|
+
const SVFG* svfg = nullptr;
|
|
293
|
+
NodeBS retainedNodeIds;
|
|
304
294
|
};
|
|
305
295
|
|
|
306
296
|
//===----------------------------------------------------------------------===//
|
|
@@ -310,11 +300,10 @@ private:
|
|
|
310
300
|
class SlicedSVFIRView
|
|
311
301
|
{
|
|
312
302
|
public:
|
|
313
|
-
SlicedSVFIRView(SVFIR*
|
|
314
|
-
|
|
303
|
+
SlicedSVFIRView(SVFIR* svfir,
|
|
304
|
+
ThreadCallGraph& callGraph,
|
|
315
305
|
ICFG* icfg,
|
|
316
|
-
const OrderedSet<const ICFGNode*>& keepNodes
|
|
317
|
-
bool buildBridged = true);
|
|
306
|
+
const OrderedSet<const ICFGNode*>& keepNodes);
|
|
318
307
|
|
|
319
308
|
/// Get SlicedICFGView
|
|
320
309
|
inline const SlicedICFGView* getICFG() const
|
|
@@ -329,10 +318,12 @@ public:
|
|
|
329
318
|
/// Get SlicedPAGView
|
|
330
319
|
inline const SlicedPAGView* getPAG() const
|
|
331
320
|
{
|
|
321
|
+
ensurePAGView();
|
|
332
322
|
return pagView.get();
|
|
333
323
|
}
|
|
334
324
|
inline SlicedPAGView* getPAG()
|
|
335
325
|
{
|
|
326
|
+
ensurePAGView();
|
|
336
327
|
return pagView.get();
|
|
337
328
|
}
|
|
338
329
|
|
|
@@ -361,34 +352,27 @@ public:
|
|
|
361
352
|
/// Get all kept statements
|
|
362
353
|
inline const OrderedSet<const SVFStmt*>& getKeptStatements() const
|
|
363
354
|
{
|
|
364
|
-
return
|
|
355
|
+
return getPAG()->getKeptStmts();
|
|
365
356
|
}
|
|
366
357
|
|
|
367
|
-
/// In-edges of a call-graph node under the sliced ThreadCallGraph view (the
|
|
368
|
-
/// full node in-edges if no TCG view was built).
|
|
369
|
-
void getInEdgesOfCallGraphNode(const CallGraphNode* node,
|
|
370
|
-
std::vector<const CallGraphEdge*>& out) const;
|
|
371
|
-
|
|
372
|
-
/// The CallGraph the sliced analyses scan: the sliced ThreadCallGraph's
|
|
373
|
-
/// original CallGraph, or the full PAG CallGraph if no TCG view was built.
|
|
374
|
-
const CallGraph* getAnalysisCallGraph() const;
|
|
375
|
-
|
|
376
358
|
/// Dump all views to files
|
|
377
359
|
void dumpAll(const std::string& prefix) const;
|
|
378
360
|
|
|
379
361
|
/// Get original SVFIR
|
|
380
362
|
inline SVFIR* getSVFIR() const
|
|
381
363
|
{
|
|
382
|
-
return
|
|
364
|
+
return svfir;
|
|
383
365
|
}
|
|
384
366
|
|
|
385
367
|
/// Output statistics
|
|
386
368
|
void dumpStats(const std::string& prefix = "") const;
|
|
387
369
|
|
|
388
370
|
private:
|
|
389
|
-
|
|
371
|
+
void ensurePAGView() const;
|
|
372
|
+
|
|
373
|
+
SVFIR* svfir;
|
|
390
374
|
std::unique_ptr<SlicedICFGView> icfgView;
|
|
391
|
-
std::unique_ptr<SlicedPAGView> pagView;
|
|
375
|
+
mutable std::unique_ptr<SlicedPAGView> pagView;
|
|
392
376
|
std::unique_ptr<SlicedThreadCallGraphView> tcgView;
|
|
393
377
|
};
|
|
394
378
|
|
|
@@ -651,7 +635,7 @@ public:
|
|
|
651
635
|
|
|
652
636
|
friend bool operator==(const SlicedICFGNodeIter& a, const SlicedICFGNodeIter& b)
|
|
653
637
|
{
|
|
654
|
-
return a.it == b.it;
|
|
638
|
+
return a.view == b.view && a.it == b.it;
|
|
655
639
|
}
|
|
656
640
|
friend bool operator!=(const SlicedICFGNodeIter& a, const SlicedICFGNodeIter& b)
|
|
657
641
|
{
|
|
@@ -851,7 +835,7 @@ public:
|
|
|
851
835
|
}
|
|
852
836
|
friend bool operator==(const SlicedCGNodeIter& a, const SlicedCGNodeIter& b)
|
|
853
837
|
{
|
|
854
|
-
return a.it == b.it;
|
|
838
|
+
return a.view == b.view && a.it == b.it;
|
|
855
839
|
}
|
|
856
840
|
friend bool operator!=(const SlicedCGNodeIter& a, const SlicedCGNodeIter& b)
|
|
857
841
|
{
|
|
@@ -1052,7 +1036,7 @@ public:
|
|
|
1052
1036
|
}
|
|
1053
1037
|
friend bool operator==(const SlicedPAGNodeIter& a, const SlicedPAGNodeIter& b)
|
|
1054
1038
|
{
|
|
1055
|
-
return a.it == b.it;
|
|
1039
|
+
return a.view == b.view && a.it == b.it;
|
|
1056
1040
|
}
|
|
1057
1041
|
friend bool operator!=(const SlicedPAGNodeIter& a, const SlicedPAGNodeIter& b)
|
|
1058
1042
|
{
|
|
@@ -1066,7 +1050,7 @@ private:
|
|
|
1066
1050
|
|
|
1067
1051
|
//===----------------------------------------------------------------------===//
|
|
1068
1052
|
// SlicedSVFGView traits support (no bridged edges; membership is the view's
|
|
1069
|
-
// retained-node rule, so removed nodes
|
|
1053
|
+
// retained-node rule, so removed nodes never enter SCC/worklist traversal).
|
|
1070
1054
|
//===----------------------------------------------------------------------===//
|
|
1071
1055
|
|
|
1072
1056
|
using SlicedSVFGNodeRef = SlicedNodeRef<SlicedSVFGView, SVFGNode>;
|
|
@@ -1258,7 +1242,7 @@ public:
|
|
|
1258
1242
|
}
|
|
1259
1243
|
friend bool operator==(const SlicedSVFGNodeIter& a, const SlicedSVFGNodeIter& b)
|
|
1260
1244
|
{
|
|
1261
|
-
return a.it == b.it;
|
|
1245
|
+
return a.view == b.view && a.it == b.it;
|
|
1262
1246
|
}
|
|
1263
1247
|
friend bool operator!=(const SlicedSVFGNodeIter& a, const SlicedSVFGNodeIter& b)
|
|
1264
1248
|
{
|
|
@@ -1307,6 +1291,10 @@ struct GenericGraphTraits<const SlicedICFGView*>
|
|
|
1307
1291
|
{
|
|
1308
1292
|
return g->getFunEntry(fun);
|
|
1309
1293
|
}
|
|
1294
|
+
static const ICFGNode* getFunExit(const SlicedICFGView* g, const FunObjVar* fun)
|
|
1295
|
+
{
|
|
1296
|
+
return g->getFunExit(fun);
|
|
1297
|
+
}
|
|
1310
1298
|
static void getFunICFGNodes(const SlicedICFGView* g, const FunObjVar* fun,
|
|
1311
1299
|
std::vector<const ICFGNode*>& out)
|
|
1312
1300
|
{
|
|
@@ -1453,9 +1441,46 @@ struct GenericGraphTraits<const SlicedThreadCallGraphView*>
|
|
|
1453
1441
|
{
|
|
1454
1442
|
g->getInEdgesOf(n, out);
|
|
1455
1443
|
}
|
|
1456
|
-
static const
|
|
1444
|
+
static void getOutEdges(const SlicedThreadCallGraphView* g, const CallGraphNode* n,
|
|
1445
|
+
std::vector<const CallGraphEdge*>& out)
|
|
1446
|
+
{
|
|
1447
|
+
g->getOutEdgesOf(n, out);
|
|
1448
|
+
}
|
|
1449
|
+
static void getDirectCalls(const SlicedThreadCallGraphView* g,
|
|
1450
|
+
const CallGraphEdge* e,
|
|
1451
|
+
std::vector<const CallICFGNode*>& out)
|
|
1452
|
+
{
|
|
1453
|
+
g->getDirectCallsOf(e, out);
|
|
1454
|
+
}
|
|
1455
|
+
static void getIndirectCalls(const SlicedThreadCallGraphView* g,
|
|
1456
|
+
const CallGraphEdge* e,
|
|
1457
|
+
std::vector<const CallICFGNode*>& out)
|
|
1458
|
+
{
|
|
1459
|
+
g->getIndirectCallsOf(e, out);
|
|
1460
|
+
}
|
|
1461
|
+
static bool containsCallSite(const SlicedThreadCallGraphView* g,
|
|
1462
|
+
const CallGraphEdge* e,
|
|
1463
|
+
const CallICFGNode* callSite)
|
|
1464
|
+
{
|
|
1465
|
+
return g->containsCallSite(e, callSite);
|
|
1466
|
+
}
|
|
1467
|
+
static void getCallees(const SlicedThreadCallGraphView* g,
|
|
1468
|
+
const CallICFGNode* callSite,
|
|
1469
|
+
CallGraph::FunctionSet& callees)
|
|
1457
1470
|
{
|
|
1458
|
-
|
|
1471
|
+
g->getCalleesOf(callSite, callees);
|
|
1472
|
+
}
|
|
1473
|
+
static void getForkEdges(const SlicedThreadCallGraphView* g,
|
|
1474
|
+
const CallICFGNode* callSite,
|
|
1475
|
+
std::vector<const CallGraphEdge*>& out)
|
|
1476
|
+
{
|
|
1477
|
+
g->getForkEdgesOf(callSite, out);
|
|
1478
|
+
}
|
|
1479
|
+
static void getJoinEdges(const SlicedThreadCallGraphView* g,
|
|
1480
|
+
const CallICFGNode* callSite,
|
|
1481
|
+
std::vector<const CallGraphEdge*>& out)
|
|
1482
|
+
{
|
|
1483
|
+
g->getJoinEdgesOf(callSite, out);
|
|
1459
1484
|
}
|
|
1460
1485
|
//@}
|
|
1461
1486
|
|
|
@@ -1514,7 +1539,7 @@ struct GenericGraphTraits<const SlicedThreadCallGraphView*>
|
|
|
1514
1539
|
}
|
|
1515
1540
|
static NodeRef getNode(const SlicedThreadCallGraphView* v, NodeID id)
|
|
1516
1541
|
{
|
|
1517
|
-
const CallGraphNode* raw = v->
|
|
1542
|
+
const CallGraphNode* raw = v->getBackingCallGraph()->getGNode(id);
|
|
1518
1543
|
return NodeRef{v, (raw != nullptr && v->isKeptNode(raw)) ? raw : nullptr};
|
|
1519
1544
|
}
|
|
1520
1545
|
};
|
|
@@ -1685,6 +1710,7 @@ struct GenericGraphTraits<const SlicedSVFGView*>
|
|
|
1685
1710
|
using nodes_iterator = SlicedSVFGNodeIter;
|
|
1686
1711
|
using ChildIteratorType = SlicedSVFGChildIterImpl<true>;
|
|
1687
1712
|
using ChildEdgeIteratorType = SlicedSVFGEdgeIterImpl<true>;
|
|
1713
|
+
static constexpr bool isFilteredGraph = true;
|
|
1688
1714
|
|
|
1689
1715
|
static const SVFGNode* getRawNode(NodeRef n)
|
|
1690
1716
|
{
|
|
@@ -1697,6 +1723,11 @@ struct GenericGraphTraits<const SlicedSVFGView*>
|
|
|
1697
1723
|
return g->isKeptNode(n);
|
|
1698
1724
|
}
|
|
1699
1725
|
|
|
1726
|
+
static bool containsEdge(const SlicedSVFGView* g, const SVFGEdge* e)
|
|
1727
|
+
{
|
|
1728
|
+
return g->isKeptEdge(e);
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1700
1731
|
static NodeRef getEntryNode(const SlicedSVFGView*)
|
|
1701
1732
|
{
|
|
1702
1733
|
return NodeRef{};
|
|
@@ -1747,6 +1778,10 @@ struct GenericGraphTraits<const SlicedSVFGView*>
|
|
|
1747
1778
|
{
|
|
1748
1779
|
return n.raw->getId();
|
|
1749
1780
|
}
|
|
1781
|
+
static unsigned graphSize(const SlicedSVFGView* v)
|
|
1782
|
+
{
|
|
1783
|
+
return static_cast<unsigned>(v->getKeptNodeCount());
|
|
1784
|
+
}
|
|
1750
1785
|
static NodeRef getNode(const SlicedSVFGView* v, NodeID id)
|
|
1751
1786
|
{
|
|
1752
1787
|
const SVFGNode* raw =
|
|
@@ -405,4 +405,41 @@ private:
|
|
|
405
405
|
|
|
406
406
|
} // End namespace SVF
|
|
407
407
|
|
|
408
|
+
namespace SVF
|
|
409
|
+
{
|
|
410
|
+
|
|
411
|
+
/// Thread-specific relations are indexed by callsite rather than represented
|
|
412
|
+
/// uniformly in CallGraph node adjacency. In particular, ThreadJoinEdge is not
|
|
413
|
+
/// added to adjacency because it would introduce artificial SCC cycles.
|
|
414
|
+
template<>
|
|
415
|
+
struct GenericGraphTraits<SVF::ThreadCallGraph*>
|
|
416
|
+
: public GenericGraphTraits<SVF::CallGraph*>
|
|
417
|
+
{
|
|
418
|
+
static void getForkEdges(const SVF::ThreadCallGraph* graph,
|
|
419
|
+
const SVF::CallICFGNode* callSite,
|
|
420
|
+
std::vector<const SVF::CallGraphEdge*>& out)
|
|
421
|
+
{
|
|
422
|
+
out.clear();
|
|
423
|
+
if (!graph->hasThreadForkEdge(callSite))
|
|
424
|
+
return;
|
|
425
|
+
for (auto it = graph->getForkEdgeBegin(callSite),
|
|
426
|
+
end = graph->getForkEdgeEnd(callSite); it != end; ++it)
|
|
427
|
+
out.push_back(*it);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
static void getJoinEdges(const SVF::ThreadCallGraph* graph,
|
|
431
|
+
const SVF::CallICFGNode* callSite,
|
|
432
|
+
std::vector<const SVF::CallGraphEdge*>& out)
|
|
433
|
+
{
|
|
434
|
+
out.clear();
|
|
435
|
+
if (!graph->hasThreadJoinEdge(callSite))
|
|
436
|
+
return;
|
|
437
|
+
for (auto it = graph->getJoinEdgeBegin(callSite),
|
|
438
|
+
end = graph->getJoinEdgeEnd(callSite); it != end; ++it)
|
|
439
|
+
out.push_back(*it);
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
} // End namespace SVF
|
|
444
|
+
|
|
408
445
|
#endif /* RCG_H_ */
|