svf-tools 1.0.644 → 1.0.645
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/CFL/CFLSolver.h +146 -191
- package/svf/lib/CFL/CFLSolver.cpp +6 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.645",
|
|
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": {
|
|
@@ -38,173 +38,7 @@ using namespace std;
|
|
|
38
38
|
|
|
39
39
|
namespace SVF
|
|
40
40
|
{
|
|
41
|
-
|
|
42
41
|
typedef GrammarBase::Symbol Label;
|
|
43
|
-
/*!
|
|
44
|
-
* Adjacency-list graph representation
|
|
45
|
-
*/
|
|
46
|
-
class CFLData
|
|
47
|
-
{
|
|
48
|
-
public:
|
|
49
|
-
typedef std::map<const Label, NodeBS> TypeMap; // Label with SparseBitVector of NodeID
|
|
50
|
-
typedef std::unordered_map<NodeID, TypeMap> DataMap; // Each Node has a TypeMap
|
|
51
|
-
typedef typename DataMap::iterator iterator; // iterator for each node
|
|
52
|
-
typedef typename DataMap::const_iterator const_iterator; // const iterator
|
|
53
|
-
|
|
54
|
-
protected:
|
|
55
|
-
DataMap succMap; // succ map for nodes contains Label: Edgeset
|
|
56
|
-
DataMap predMap; // pred map for nodes contains Label: edgeset
|
|
57
|
-
const NodeBS emptyData; // ??
|
|
58
|
-
NodeBS diff; // ??
|
|
59
|
-
|
|
60
|
-
// union/add data
|
|
61
|
-
//@{
|
|
62
|
-
inline bool addPred(const NodeID key, const NodeID src, const Label ty)
|
|
63
|
-
{
|
|
64
|
-
return predMap[key][ty].test_and_set(src);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
inline bool addSucc(const NodeID key, const NodeID dst, const Label ty)
|
|
68
|
-
{
|
|
69
|
-
return succMap[key][ty].test_and_set(dst);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
inline bool addPreds(const NodeID key, const NodeBS& data, const Label ty)
|
|
73
|
-
{
|
|
74
|
-
if (data.empty())
|
|
75
|
-
return false;
|
|
76
|
-
return predMap[key][ty] |= data; // union of sparsebitvector (add to LHS)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
inline bool addSuccs(const NodeID key, const NodeBS& data, const Label ty)
|
|
80
|
-
{
|
|
81
|
-
if (data.empty())
|
|
82
|
-
return false;
|
|
83
|
-
return succMap[key][ty] |= data; // // union of sparsebitvector (add to LHS)
|
|
84
|
-
}
|
|
85
|
-
//@}
|
|
86
|
-
|
|
87
|
-
public:
|
|
88
|
-
// Constructor
|
|
89
|
-
CFLData()
|
|
90
|
-
{}
|
|
91
|
-
|
|
92
|
-
// Destructor
|
|
93
|
-
virtual ~CFLData()
|
|
94
|
-
{}
|
|
95
|
-
|
|
96
|
-
virtual void clear()
|
|
97
|
-
{
|
|
98
|
-
succMap.clear();
|
|
99
|
-
predMap.clear();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
inline const_iterator begin() const
|
|
103
|
-
{
|
|
104
|
-
return succMap.begin();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
inline const_iterator end() const
|
|
108
|
-
{
|
|
109
|
-
return succMap.end();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
inline iterator begin()
|
|
113
|
-
{
|
|
114
|
-
return succMap.begin();
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
inline iterator end()
|
|
118
|
-
{
|
|
119
|
-
return succMap.end();
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
inline DataMap& getSuccMap()
|
|
123
|
-
{
|
|
124
|
-
return succMap;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
inline DataMap& getPredMap()
|
|
128
|
-
{
|
|
129
|
-
return predMap;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
inline TypeMap& getSuccMap(const NodeID key)
|
|
133
|
-
{
|
|
134
|
-
return succMap[key];
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
inline TypeMap& getPredMap(const NodeID key)
|
|
138
|
-
{
|
|
139
|
-
return predMap[key];
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
inline NodeBS& getSuccs(const NodeID key, const Label ty)
|
|
143
|
-
{
|
|
144
|
-
return succMap[key][ty];
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
inline NodeBS& getPreds(const NodeID key, const Label ty)
|
|
148
|
-
{
|
|
149
|
-
return predMap[key][ty];
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Alias data operations
|
|
153
|
-
//@{
|
|
154
|
-
inline bool addEdge(const NodeID src, const NodeID dst, const Label ty)
|
|
155
|
-
{
|
|
156
|
-
addSucc(src, dst, ty);
|
|
157
|
-
return addPred(dst, src, ty);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/// add edges and return the set of added edges (dst) for src
|
|
161
|
-
inline NodeBS addEdges(const NodeID src, const NodeBS& dstData, const Label ty)
|
|
162
|
-
{
|
|
163
|
-
NodeBS newDsts;
|
|
164
|
-
if (addSuccs(src, dstData, ty))
|
|
165
|
-
{
|
|
166
|
-
for (const NodeID datum: dstData)
|
|
167
|
-
if (addPred(datum, src, ty))
|
|
168
|
-
newDsts.set(datum);
|
|
169
|
-
}
|
|
170
|
-
return newDsts;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/// add edges and return the set of added edges (src) for dst
|
|
174
|
-
inline NodeBS addEdges(const NodeBS& srcData, const NodeID dst, const Label ty)
|
|
175
|
-
{
|
|
176
|
-
NodeBS newSrcs;
|
|
177
|
-
if (addPreds(dst, srcData, ty))
|
|
178
|
-
{
|
|
179
|
-
for (const NodeID datum: srcData)
|
|
180
|
-
if (addSucc(datum, dst, ty))
|
|
181
|
-
newSrcs.set(datum);
|
|
182
|
-
}
|
|
183
|
-
return newSrcs;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/// find src -> find src[ty] -> find dst in set
|
|
187
|
-
inline bool hasEdge(const NodeID src, const NodeID dst, const Label ty)
|
|
188
|
-
{
|
|
189
|
-
const_iterator iter1 = succMap.find(src);
|
|
190
|
-
if (iter1 == succMap.end())
|
|
191
|
-
return false;
|
|
192
|
-
|
|
193
|
-
auto iter2 = iter1->second.find(ty);
|
|
194
|
-
if (iter2 == iter1->second.end())
|
|
195
|
-
return false;
|
|
196
|
-
|
|
197
|
-
return iter2->second.test(dst);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/* This is a dataset version, to be modified to a cflData version */
|
|
201
|
-
inline void clearEdges(const NodeID key)
|
|
202
|
-
{
|
|
203
|
-
succMap[key].clear();
|
|
204
|
-
predMap[key].clear();
|
|
205
|
-
}
|
|
206
|
-
//@}
|
|
207
|
-
};
|
|
208
42
|
|
|
209
43
|
/*!
|
|
210
44
|
* Hybrid graph representation for transitive relations
|
|
@@ -388,51 +222,172 @@ protected:
|
|
|
388
222
|
class POCRSolver : public CFLSolver
|
|
389
223
|
{
|
|
390
224
|
public:
|
|
391
|
-
|
|
225
|
+
typedef std::map<const Label, NodeBS> TypeMap; // Label with SparseBitVector of NodeID
|
|
226
|
+
typedef std::unordered_map<NodeID, TypeMap> DataMap; // Each Node has a TypeMap
|
|
227
|
+
typedef typename DataMap::iterator iterator; // iterator for each node
|
|
228
|
+
typedef typename DataMap::const_iterator const_iterator;
|
|
229
|
+
|
|
230
|
+
protected:
|
|
231
|
+
DataMap succMap; // succ map for nodes contains Label: Edgeset
|
|
232
|
+
DataMap predMap; // pred map for nodes contains Label: edgeset
|
|
233
|
+
const NodeBS emptyData; // ??
|
|
234
|
+
NodeBS diff;
|
|
235
|
+
// union/add data
|
|
236
|
+
//@{
|
|
237
|
+
inline bool addPred(const NodeID key, const NodeID src, const Label ty)
|
|
392
238
|
{
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
239
|
+
return predMap[key][ty].test_and_set(src);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
inline bool addSucc(const NodeID key, const NodeID dst, const Label ty)
|
|
243
|
+
{
|
|
244
|
+
return succMap[key][ty].test_and_set(dst);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
inline bool addPreds(const NodeID key, const NodeBS& data, const Label ty)
|
|
248
|
+
{
|
|
249
|
+
if (data.empty())
|
|
250
|
+
return false;
|
|
251
|
+
return predMap[key][ty] |= data; // union of sparsebitvector (add to LHS)
|
|
399
252
|
}
|
|
400
|
-
|
|
401
|
-
|
|
253
|
+
|
|
254
|
+
inline bool addSuccs(const NodeID key, const NodeBS& data, const Label ty)
|
|
402
255
|
{
|
|
403
|
-
|
|
256
|
+
if (data.empty())
|
|
257
|
+
return false;
|
|
258
|
+
return succMap[key][ty] |= data; // // union of sparsebitvector (add to LHS)
|
|
404
259
|
}
|
|
260
|
+
//@}
|
|
261
|
+
public:
|
|
405
262
|
|
|
406
|
-
|
|
407
|
-
|
|
263
|
+
virtual void clear()
|
|
264
|
+
{
|
|
265
|
+
succMap.clear();
|
|
266
|
+
predMap.clear();
|
|
267
|
+
}
|
|
408
268
|
|
|
409
|
-
|
|
410
|
-
|
|
269
|
+
inline const_iterator begin() const
|
|
270
|
+
{
|
|
271
|
+
return succMap.begin();
|
|
272
|
+
}
|
|
411
273
|
|
|
412
|
-
|
|
274
|
+
inline const_iterator end() const
|
|
413
275
|
{
|
|
414
|
-
return
|
|
276
|
+
return succMap.end();
|
|
415
277
|
}
|
|
416
278
|
|
|
417
|
-
|
|
279
|
+
inline iterator begin()
|
|
418
280
|
{
|
|
419
|
-
return
|
|
281
|
+
return succMap.begin();
|
|
420
282
|
}
|
|
421
283
|
|
|
422
|
-
|
|
284
|
+
inline iterator end()
|
|
285
|
+
{
|
|
286
|
+
return succMap.end();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
inline DataMap& getSuccMap()
|
|
290
|
+
{
|
|
291
|
+
return succMap;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
inline DataMap& getPredMap()
|
|
295
|
+
{
|
|
296
|
+
return predMap;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
inline TypeMap& getSuccMap(const NodeID key)
|
|
300
|
+
{
|
|
301
|
+
return succMap[key];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
inline TypeMap& getPredMap(const NodeID key)
|
|
305
|
+
{
|
|
306
|
+
return predMap[key];
|
|
307
|
+
}
|
|
423
308
|
|
|
424
|
-
|
|
309
|
+
inline NodeBS& getSuccs(const NodeID key, const Label ty)
|
|
425
310
|
{
|
|
426
|
-
return
|
|
311
|
+
return succMap[key][ty];
|
|
427
312
|
}
|
|
428
313
|
|
|
314
|
+
inline NodeBS& getPreds(const NodeID key, const Label ty)
|
|
315
|
+
{
|
|
316
|
+
return predMap[key][ty];
|
|
317
|
+
}
|
|
429
318
|
|
|
430
|
-
|
|
319
|
+
// Alias data operations
|
|
320
|
+
//@{
|
|
321
|
+
inline bool addEdge(const NodeID src, const NodeID dst, const Label ty)
|
|
431
322
|
{
|
|
432
|
-
|
|
323
|
+
addSucc(src, dst, ty);
|
|
324
|
+
return addPred(dst, src, ty);
|
|
433
325
|
}
|
|
434
|
-
|
|
435
|
-
|
|
326
|
+
|
|
327
|
+
/// add edges and return the set of added edges (dst) for src
|
|
328
|
+
inline NodeBS addEdges(const NodeID src, const NodeBS& dstData, const Label ty)
|
|
329
|
+
{
|
|
330
|
+
NodeBS newDsts;
|
|
331
|
+
if (addSuccs(src, dstData, ty))
|
|
332
|
+
{
|
|
333
|
+
for (const NodeID datum: dstData)
|
|
334
|
+
if (addPred(datum, src, ty))
|
|
335
|
+
newDsts.set(datum);
|
|
336
|
+
}
|
|
337
|
+
return newDsts;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/// add edges and return the set of added edges (src) for dst
|
|
341
|
+
inline NodeBS addEdges(const NodeBS& srcData, const NodeID dst, const Label ty)
|
|
342
|
+
{
|
|
343
|
+
NodeBS newSrcs;
|
|
344
|
+
if (addPreds(dst, srcData, ty))
|
|
345
|
+
{
|
|
346
|
+
for (const NodeID datum: srcData)
|
|
347
|
+
if (addSucc(datum, dst, ty))
|
|
348
|
+
newSrcs.set(datum);
|
|
349
|
+
}
|
|
350
|
+
return newSrcs;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/// find src -> find src[ty] -> find dst in set
|
|
354
|
+
inline bool hasEdge(const NodeID src, const NodeID dst, const Label ty)
|
|
355
|
+
{
|
|
356
|
+
const_iterator iter1 = succMap.find(src);
|
|
357
|
+
if (iter1 == succMap.end())
|
|
358
|
+
return false;
|
|
359
|
+
|
|
360
|
+
auto iter2 = iter1->second.find(ty);
|
|
361
|
+
if (iter2 == iter1->second.end())
|
|
362
|
+
return false;
|
|
363
|
+
|
|
364
|
+
return iter2->second.test(dst);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/* This is a dataset version, to be modified to a cflData version */
|
|
368
|
+
inline void clearEdges(const NodeID key)
|
|
369
|
+
{
|
|
370
|
+
succMap[key].clear();
|
|
371
|
+
predMap[key].clear();
|
|
372
|
+
}
|
|
373
|
+
//@}
|
|
374
|
+
|
|
375
|
+
POCRSolver(CFLGraph* _graph, CFLGrammar* _grammar) : CFLSolver(_graph, _grammar)
|
|
376
|
+
{
|
|
377
|
+
buildCFLData();
|
|
378
|
+
}
|
|
379
|
+
/// Destructor
|
|
380
|
+
virtual ~POCRSolver()
|
|
381
|
+
{
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/// Process CFLEdge
|
|
385
|
+
virtual void processCFLEdge(const CFLEdge* Y_edge);
|
|
386
|
+
|
|
387
|
+
/// Init CFLData
|
|
388
|
+
virtual void buildCFLData();
|
|
389
|
+
|
|
390
|
+
virtual void initialize();
|
|
436
391
|
};
|
|
437
392
|
}
|
|
438
393
|
|
|
@@ -163,8 +163,8 @@ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge)
|
|
|
163
163
|
for(const Production& prod : grammar->getProdsFromFirstRHS(Y))
|
|
164
164
|
{
|
|
165
165
|
Symbol X = grammar->getLHSSymbol(prod);
|
|
166
|
-
NodeBS diffDsts = addEdges(i->getId(),
|
|
167
|
-
numOfChecks +=
|
|
166
|
+
NodeBS diffDsts = addEdges(i->getId(), getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)], X);
|
|
167
|
+
numOfChecks += getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)].count();
|
|
168
168
|
for (NodeID diffDst: diffDsts)
|
|
169
169
|
{
|
|
170
170
|
const CFLEdge* newEdge = graph->addCFLEdge(i, graph->getGNode(diffDst), X);
|
|
@@ -179,8 +179,8 @@ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge)
|
|
|
179
179
|
for(const Production& prod : grammar->getProdsFromSecondRHS(Y))
|
|
180
180
|
{
|
|
181
181
|
Symbol X = grammar->getLHSSymbol(prod);
|
|
182
|
-
NodeBS diffSrcs = addEdges(
|
|
183
|
-
numOfChecks +=
|
|
182
|
+
NodeBS diffSrcs = addEdges(getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)], j->getId(), X);
|
|
183
|
+
numOfChecks += getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)].count();
|
|
184
184
|
for (NodeID diffSrc: diffSrcs)
|
|
185
185
|
{
|
|
186
186
|
const CFLEdge* newEdge = graph->addCFLEdge(graph->getGNode(diffSrc), j, X);
|
|
@@ -203,16 +203,15 @@ void POCRSolver::initialize()
|
|
|
203
203
|
/// add X(i,i) if not exist to E and to worklist
|
|
204
204
|
for(const Production& prod : grammar->getEpsilonProds())
|
|
205
205
|
{
|
|
206
|
-
for(auto IDMap :
|
|
206
|
+
for(auto IDMap : getSuccMap())
|
|
207
207
|
{
|
|
208
208
|
Symbol X = grammar->getLHSSymbol(prod);
|
|
209
|
-
if (
|
|
209
|
+
if (addEdge(IDMap.first, IDMap.first, X))
|
|
210
210
|
{
|
|
211
211
|
CFLNode* i = graph->getGNode(IDMap.first);
|
|
212
212
|
const CFLEdge* newEdge = graph->addCFLEdge(i, i, X);
|
|
213
213
|
pushIntoWorklist(newEdge);
|
|
214
214
|
}
|
|
215
|
-
|
|
216
215
|
}
|
|
217
216
|
}
|
|
218
217
|
}
|