svf-tools 1.0.642 → 1.0.644

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.642",
3
+ "version": "1.0.644",
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": {
@@ -32,8 +32,6 @@
32
32
 
33
33
  #include "CFL/CFLBase.h"
34
34
  #include "CFL/CFLStat.h"
35
- #include "CFL/CFLData.h"
36
- #include "CFL/CFLDataBuilder.h"
37
35
 
38
36
  namespace SVF
39
37
  {
@@ -142,34 +140,12 @@ private:
142
140
  class POCRAlias : public CFLAlias
143
141
  {
144
142
  public:
145
- static double timeOfBuildCFLData; // Time of building CFLData from CFLGraph
146
-
147
143
  POCRAlias(SVFIR* ir) : CFLAlias(ir)
148
144
  {
149
- if (!_cflData)
150
- _cflData = new CFLData();
151
- }
152
-
153
- /// Destructor
154
- virtual ~POCRAlias()
155
- {
156
- delete _cflData;
157
- }
158
-
159
- CFLData* cflData()
160
- {
161
- return _cflData;
162
145
  }
163
146
 
164
147
  /// Initialize the grammar, graph, CFLData, solver
165
148
  virtual void initialize();
166
-
167
- /// Init CFLData
168
- virtual void buildCFLData();
169
-
170
- private:
171
- /// Graph dataset
172
- CFLData* _cflData;
173
149
  };
174
150
  } // End namespace SVF
175
151
 
@@ -24,7 +24,7 @@
24
24
  * CFLSolver.h
25
25
  *
26
26
  * Created on: March 5, 2022
27
- * Author: Yulei Sui
27
+ * Author: Yulei Sui, Yuxiang Lei
28
28
  */
29
29
 
30
30
  #ifndef INCLUDE_CFL_CFLSolver_H_
@@ -33,12 +33,285 @@
33
33
  #include "Graphs/CFLGraph.h"
34
34
  #include "CFL/CFLGrammar.h"
35
35
  #include "Util/WorkList.h"
36
- #include "CFL/CFLData.h"
37
36
 
37
+ using namespace std;
38
38
 
39
39
  namespace SVF
40
40
  {
41
41
 
42
+ 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
+
209
+ /*!
210
+ * Hybrid graph representation for transitive relations
211
+ * The implementation is based on
212
+ * Yuxiang Lei, Yulei Sui, Shuo Ding, and Qirun Zhang.
213
+ * Taming Transitive Redundancy for Context-Free Language Reachability.
214
+ * ACM SIGPLAN Conference on Object-Oriented Programming, Systems, Languages, and Applications
215
+ */
216
+ class HybridData
217
+ {
218
+ public:
219
+ struct TreeNode
220
+ {
221
+ NodeID id;
222
+ std::unordered_set<TreeNode*> children;
223
+
224
+ TreeNode(NodeID nId) : id(nId)
225
+ {}
226
+
227
+ ~TreeNode()
228
+ {
229
+ }
230
+
231
+ inline bool operator==(const TreeNode& rhs) const
232
+ {
233
+ return id == rhs.id;
234
+ }
235
+
236
+ inline bool operator<(const TreeNode& rhs) const
237
+ {
238
+ return id < rhs.id;
239
+ }
240
+ };
241
+
242
+
243
+ public:
244
+ Map<NodeID, std::unordered_map<NodeID, TreeNode*>> indMap; // indMap[v][u] points to node v in tree(u)
245
+
246
+ HybridData()
247
+ {}
248
+
249
+ ~HybridData()
250
+ {
251
+ for (auto iter1: indMap)
252
+ {
253
+ for (auto iter2: iter1.second)
254
+ {
255
+ delete iter2.second;
256
+ iter2.second = NULL;
257
+ }
258
+ }
259
+ }
260
+
261
+ bool hasInd(NodeID src, NodeID dst)
262
+ {
263
+ auto it = indMap.find(dst);
264
+ if (it == indMap.end())
265
+ return false;
266
+ return (it->second.find(src) != it->second.end());
267
+ }
268
+
269
+ /// Add a node dst to tree(src)
270
+ TreeNode* addInd(NodeID src, NodeID dst)
271
+ {
272
+ auto resIns = indMap[dst].insert(std::make_pair(src, new TreeNode(dst)));
273
+ if (resIns.second)
274
+ return resIns.first->second;
275
+ return nullptr;
276
+ }
277
+
278
+ /// Get the node dst in tree(src)
279
+ TreeNode* getNode(NodeID src, NodeID dst)
280
+ {
281
+ return indMap[dst][src];
282
+ }
283
+
284
+ /// add v into desc(x) as a child of u
285
+ void insertEdge(TreeNode* u, TreeNode* v)
286
+ {
287
+ u->children.insert(v);
288
+ }
289
+
290
+ void addArc(NodeID src, NodeID dst)
291
+ {
292
+ if (!hasInd(src, dst))
293
+ {
294
+ for (auto iter: indMap[src])
295
+ {
296
+ meld(iter.first, getNode(iter.first, src), getNode(dst, dst));
297
+ }
298
+ }
299
+ }
300
+
301
+ void meld(NodeID x, TreeNode* uNode, TreeNode* vNode)
302
+ {
303
+ TreeNode* newVNode = addInd(x, vNode->id);
304
+ if (!newVNode)
305
+ return;
306
+
307
+ insertEdge(uNode, newVNode);
308
+ for (TreeNode* vChild: vNode->children)
309
+ {
310
+ meld(x, newVNode, vChild);
311
+ }
312
+ }
313
+ };
314
+
42
315
  class CFLSolver
43
316
  {
44
317
 
@@ -54,20 +327,20 @@ public:
54
327
  {
55
328
  }
56
329
 
57
- ~CFLSolver()
330
+ virtual ~CFLSolver()
58
331
  {
59
332
  delete graph;
60
333
  delete grammar;
61
334
  }
62
335
 
63
336
  /// Initialize worklist
64
- void initialize();
337
+ virtual void initialize();
65
338
 
66
339
  /// Process CFLEdge
67
- void processCFLEdge(const CFLEdge* Y_edge);
340
+ virtual void processCFLEdge(const CFLEdge* Y_edge);
68
341
 
69
342
  /// Start solving
70
- void solve();
343
+ virtual void solve();
71
344
 
72
345
  /// Return CFL Graph
73
346
  inline const CFLGraph* getGraph() const
@@ -80,11 +353,11 @@ public:
80
353
  {
81
354
  return grammar;
82
355
  }
83
- inline bool pushIntoWorklist(const CFLEdge* item)
356
+ virtual inline bool pushIntoWorklist(const CFLEdge* item)
84
357
  {
85
358
  return worklist.push(item);
86
359
  }
87
- inline bool isWorklistEmpty()
360
+ virtual inline bool isWorklistEmpty()
88
361
  {
89
362
  return worklist.empty();
90
363
  }
@@ -103,7 +376,7 @@ protected:
103
376
  }
104
377
  //@}
105
378
 
106
- private:
379
+ protected:
107
380
  CFLGraph* graph;
108
381
  CFLGrammar* grammar;
109
382
  /// Worklist for resolution
@@ -114,22 +387,52 @@ private:
114
387
  /// Solver Utilize CFLData
115
388
  class POCRSolver : public CFLSolver
116
389
  {
390
+ public:
391
+ POCRSolver(CFLGraph* _graph, CFLGrammar* _grammar) : CFLSolver(_graph, _grammar), cflData(NULL)
392
+ {
393
+ if (!cflData)
394
+ {
395
+ cflData = new CFLData();
396
+ // Build CFL Data
397
+ buildCFLData();
398
+ }
399
+ }
117
400
  /// Destructor
118
401
  virtual ~POCRSolver()
119
402
  {
120
- delete _cflData;
403
+ delete cflData;
404
+ }
405
+
406
+ /// Process CFLEdge
407
+ virtual void processCFLEdge(const CFLEdge* Y_edge);
408
+
409
+ /// Init CFLData
410
+ virtual void buildCFLData();
411
+
412
+ virtual bool addEdge(const CFLNode* src, const CFLNode* dst, const Label ty)
413
+ {
414
+ return cflData->addEdge(src->getId(), dst->getId(), ty);
121
415
  }
122
416
 
123
- CFLData* cflData()
417
+ virtual bool addEdge(const NodeID srcId, const NodeID dstId, const Label ty)
124
418
  {
125
- return _cflData;
419
+ return cflData->addEdge(srcId, dstId, ty);
126
420
  }
127
421
 
128
- //virtual void initialize();
422
+ virtual void initialize();
129
423
 
130
- private:
131
- CFLData* _cflData;
424
+ virtual NodeBS addEdges(const NodeID srcId, const NodeBS& dstData, const Label ty)
425
+ {
426
+ return cflData->addEdges(srcId, dstData, ty);
427
+ }
132
428
 
429
+
430
+ virtual NodeBS addEdges(const NodeBS& srcData, const NodeID dstId, const Label ty)
431
+ {
432
+ return cflData->addEdges(srcData, dstId, ty);
433
+ }
434
+ private:
435
+ CFLData* cflData;
133
436
  };
134
437
  }
135
438
 
@@ -238,8 +238,6 @@ void CFLAlias::solve()
238
238
  timeOfSolving += (end - start) / TIMEINTERVAL;
239
239
  }
240
240
 
241
- double POCRAlias::timeOfBuildCFLData = 0; // Time of building CFLData from CFLGraph
242
-
243
241
  void POCRAlias::initialize()
244
242
  {
245
243
  stat = new CFLStat(this);
@@ -250,26 +248,9 @@ void POCRAlias::initialize()
250
248
  // Build CFL Graph
251
249
  buildCFLGraph();
252
250
 
253
- // Build CFL Data
254
- buildCFLData();
255
-
256
251
  // Normalize CFL Grammar
257
252
  normalizeCFLGrammar();
258
253
 
259
- // Initialize sovler
260
- solver = new CFLSolver(graph, grammar);
254
+ // Initialize POCRSolver
255
+ solver = new POCRSolver(graph, grammar);
261
256
  }
262
-
263
-
264
- void POCRAlias::buildCFLData()
265
- {
266
- // Start building CFLGraph
267
- double start = stat->getClk(true);
268
-
269
- CFLDataBuilder cflDataBuilder = CFLDataBuilder(graph);
270
- _cflData = cflDataBuilder.build();
271
-
272
- // Get time of build graph
273
- double end = stat->getClk(true);
274
- timeOfBuildCFLData += (end - start) / TIMEINTERVAL;
275
- }
@@ -127,4 +127,92 @@ void CFLSolver::solve()
127
127
  const CFLEdge* Y_edge = popFromWorklist();
128
128
  processCFLEdge(Y_edge);
129
129
  }
130
+ }
131
+
132
+ void POCRSolver::buildCFLData()
133
+ {
134
+ for (CFLEdge* edge: graph->getCFLEdges())
135
+ addEdge(edge->getSrcID(), edge->getDstID(), edge->getEdgeKind());
136
+ }
137
+
138
+ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge)
139
+ {
140
+ CFLNode* i = Y_edge->getSrcNode();
141
+ CFLNode* j = Y_edge->getDstNode();
142
+
143
+ /// For each production X -> Y
144
+ /// add X(i,j) if not exist to E and to worklist
145
+ Symbol Y = Y_edge->getEdgeKind();
146
+ if (grammar->hasProdsFromSingleRHS(Y))
147
+ for(const Production& prod : grammar->getProdsFromSingleRHS(Y))
148
+ {
149
+ Symbol X = grammar->getLHSSymbol(prod);
150
+ numOfChecks++;
151
+ if (addEdge(i->getId(), j->getId(), X))
152
+ {
153
+ const CFLEdge* newEdge = graph->addCFLEdge(Y_edge->getSrcNode(), Y_edge->getDstNode(), X);
154
+ pushIntoWorklist(newEdge);
155
+ }
156
+
157
+ }
158
+
159
+ /// For each production X -> Y Z
160
+ /// Foreach outgoing edge Z(j,k) from node j do
161
+ /// add X(i,k) if not exist to E and to worklist
162
+ if (grammar->hasProdsFromFirstRHS(Y))
163
+ for(const Production& prod : grammar->getProdsFromFirstRHS(Y))
164
+ {
165
+ Symbol X = grammar->getLHSSymbol(prod);
166
+ NodeBS diffDsts = addEdges(i->getId(), cflData->getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)], X);
167
+ numOfChecks += cflData->getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)].count();
168
+ for (NodeID diffDst: diffDsts)
169
+ {
170
+ const CFLEdge* newEdge = graph->addCFLEdge(i, graph->getGNode(diffDst), X);
171
+ pushIntoWorklist(newEdge);
172
+ }
173
+ }
174
+
175
+ /// For each production X -> Z Y
176
+ /// Foreach incoming edge Z(k,i) to node i do
177
+ /// add X(k,j) if not exist to E and to worklist
178
+ if(grammar->hasProdsFromSecondRHS(Y))
179
+ for(const Production& prod : grammar->getProdsFromSecondRHS(Y))
180
+ {
181
+ Symbol X = grammar->getLHSSymbol(prod);
182
+ NodeBS diffSrcs = addEdges(cflData->getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)], j->getId(), X);
183
+ numOfChecks += cflData->getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)].count();
184
+ for (NodeID diffSrc: diffSrcs)
185
+ {
186
+ const CFLEdge* newEdge = graph->addCFLEdge(graph->getGNode(diffSrc), j, X);
187
+ pushIntoWorklist(newEdge);
188
+ }
189
+ }
190
+ }
191
+
192
+ void POCRSolver::initialize()
193
+ {
194
+ for(auto it = graph->begin(); it!= graph->end(); it++)
195
+ {
196
+ for(const CFLEdge* edge : (*it).second->getOutEdges())
197
+ {
198
+ pushIntoWorklist(edge);
199
+ }
200
+ }
201
+
202
+ /// Foreach production X -> epsilon
203
+ /// add X(i,i) if not exist to E and to worklist
204
+ for(const Production& prod : grammar->getEpsilonProds())
205
+ {
206
+ for(auto IDMap : cflData->getSuccMap())
207
+ {
208
+ Symbol X = grammar->getLHSSymbol(prod);
209
+ if (cflData->addEdge(IDMap.first, IDMap.first, X))
210
+ {
211
+ CFLNode* i = graph->getGNode(IDMap.first);
212
+ const CFLEdge* newEdge = graph->addCFLEdge(i, i, X);
213
+ pushIntoWorklist(newEdge);
214
+ }
215
+
216
+ }
217
+ }
130
218
  }
@@ -883,9 +883,15 @@ SVFConstantData* LLVMModuleSet::getSVFConstantData(const ConstantData* cd)
883
883
  SVFConstantData* svfcd = nullptr;
884
884
  if(const ConstantInt* cint = SVFUtil::dyn_cast<ConstantInt>(cd))
885
885
  {
886
- /// bool true will be translated to -1 with getSExtValue, so call getZExtValue() if bitwidth = 1
887
- svfcd = new SVFConstantInt(cd->getName().str(), getSVFType(cint->getType()), cint->getZExtValue(),
888
- cint->getBitWidth() == 1? cint->getZExtValue(): cint->getSExtValue());
886
+ /// bitwidth == 1 : cint has value from getZExtValue() because `bool true` will be translated to -1 using sign extension (i.e., getSExtValue).
887
+ /// bitwidth <=64 1 : cint has value from getSExtValue()
888
+ /// bitwidth >64 1 : cint has value 0 because it represents an invalid int
889
+ if(cint->getBitWidth() == 1)
890
+ svfcd = new SVFConstantInt(cd->getName().str(), getSVFType(cint->getType()), cint->getZExtValue(), cint->getZExtValue());
891
+ else if(cint->getBitWidth() <= 64 && cint->getBitWidth() > 1)
892
+ svfcd = new SVFConstantInt(cd->getName().str(), getSVFType(cint->getType()), cint->getZExtValue(), cint->getSExtValue());
893
+ else
894
+ svfcd = new SVFConstantInt(cd->getName().str(), getSVFType(cint->getType()), 0, 0);
889
895
  }
890
896
  else if(const ConstantFP* cfp = SVFUtil::dyn_cast<ConstantFP>(cd))
891
897
  {
@@ -1,316 +0,0 @@
1
- //===----- CFLData.h -- Context Free Language Reachability Graph Data Structure--------------//
2
- //
3
- // SVF: Static Value-Flow Analysis
4
- //
5
- // Copyright (C) <2013-> <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
- * CFLData.h
25
- *
26
- * Created on: Nov 22, 2019
27
- * Author: Yuxiang Lei
28
- *
29
- * The implementation is based on
30
- * Yuxiang Lei, Yulei Sui, Shuo Ding, and Qirun Zhang.
31
- * Taming Transitive Redundancy for Context-Free Language Reachability.
32
- * ACM SIGPLAN Conference on Object-Oriented Programming, Systems, Languages, and Applications
33
- */
34
-
35
- #ifndef INCLUDE_CFL_CFGDATA_H_
36
- #define INCLUDE_CFL_CFGDATA_H_
37
-
38
- #include "Util/WorkList.h"
39
- #include "CFL/CFLGrammar.h"
40
-
41
- namespace SVF
42
- {
43
- typedef GrammarBase::Symbol Label;
44
- /*!
45
- * Adjacency-list graph representation
46
- */
47
- class CFLData
48
- {
49
- public:
50
- typedef std::map<const Label, NodeBS> TypeMap; // Label with SparseBitVector of NodeID
51
- typedef std::unordered_map<NodeID, TypeMap> DataMap; // Each Node has a TypeMap
52
- typedef typename DataMap::iterator iterator; // iterator for each node
53
- typedef typename DataMap::const_iterator const_iterator; // const iterator
54
-
55
- protected:
56
- DataMap succMap; // succ map for nodes contains Label: Edgeset
57
- DataMap predMap; // pred map for nodes contains Label: edgeset
58
- const NodeBS emptyData; // ??
59
- NodeBS diff; // ??
60
-
61
- // union/add data
62
- //@{
63
- inline bool addPred(const NodeID key, const NodeID src, const Label ty)
64
- {
65
- return predMap[key][ty].test_and_set(src);
66
- };
67
-
68
- inline bool addSucc(const NodeID key, const NodeID dst, const Label ty)
69
- {
70
- return succMap[key][ty].test_and_set(dst);
71
- };
72
-
73
- inline bool addPreds(const NodeID key, const NodeBS& data, const Label ty)
74
- {
75
- if (data.empty())
76
- return false;
77
- return predMap[key][ty] |= data; // union of sparsebitvector (add to LHS)
78
- }
79
-
80
- inline bool addSuccs(const NodeID key, const NodeBS& data, const Label ty)
81
- {
82
- if (data.empty())
83
- return false;
84
- return succMap[key][ty] |= data; // // union of sparsebitvector (add to LHS)
85
- }
86
- //@}
87
-
88
- public:
89
- // Constructor
90
- CFLData()
91
- {}
92
-
93
- // Destructor
94
- virtual ~CFLData()
95
- {}
96
-
97
- virtual void clear()
98
- {
99
- succMap.clear();
100
- predMap.clear();
101
- }
102
-
103
- inline const_iterator begin() const
104
- {
105
- return succMap.begin();
106
- }
107
-
108
- inline const_iterator end() const
109
- {
110
- return succMap.end();
111
- }
112
-
113
- inline iterator begin()
114
- {
115
- return succMap.begin();
116
- }
117
-
118
- inline iterator end()
119
- {
120
- return succMap.end();
121
- }
122
-
123
- inline DataMap& getSuccMap()
124
- {
125
- return succMap;
126
- }
127
-
128
- inline DataMap& getPredMap()
129
- {
130
- return predMap;
131
- }
132
-
133
- inline TypeMap& getSuccMap(const NodeID key)
134
- {
135
- return succMap[key];
136
- }
137
-
138
- inline TypeMap& getPredMap(const NodeID key)
139
- {
140
- return predMap[key];
141
- }
142
-
143
- inline NodeBS& getSuccs(const NodeID key, const Label ty)
144
- {
145
- return succMap[key][ty];
146
- }
147
-
148
- inline NodeBS& getPreds(const NodeID key, const Label ty)
149
- {
150
- return predMap[key][ty];
151
- }
152
-
153
- // Alias data operations
154
- //@{
155
- inline bool addEdge(const NodeID src, const NodeID dst, const Label ty)
156
- {
157
- addSucc(src, dst, ty);
158
- return addPred(dst, src, ty);
159
- }
160
-
161
- /// add edges and return the set of added edges (dst) for src
162
- inline NodeBS addEdges(const NodeID src, const NodeBS& dstData, const Label ty)
163
- {
164
- NodeBS newDsts;
165
- if (addSuccs(src, dstData, ty))
166
- {
167
- for (const NodeID datum: dstData)
168
- if (addPred(datum, src, ty))
169
- newDsts.set(datum);
170
- }
171
- return newDsts;
172
- }
173
-
174
- /// add edges and return the set of added edges (src) for dst
175
- inline NodeBS addEdges(const NodeBS& srcData, const NodeID dst, const Label ty)
176
- {
177
- NodeBS newSrcs;
178
- if (addPreds(dst, srcData, ty))
179
- {
180
- for (const NodeID datum: srcData)
181
- if (addSucc(datum, dst, ty))
182
- newSrcs.set(datum);
183
- }
184
- return newSrcs;
185
- }
186
-
187
- /// find src -> find src[ty] -> find dst in set
188
- inline bool hasEdge(const NodeID src, const NodeID dst, const Label ty)
189
- {
190
- const_iterator iter1 = succMap.find(src);
191
- if (iter1 == succMap.end())
192
- return false;
193
-
194
- auto iter2 = iter1->second.find(ty);
195
- if (iter2 == iter1->second.end())
196
- return false;
197
-
198
- return iter2->second.test(dst);
199
- }
200
-
201
- /* This is a dataset version, to be modified to a cflData version */
202
- inline void clearEdges(const NodeID key)
203
- {
204
- succMap[key].clear();
205
- predMap[key].clear();
206
- }
207
- //@}
208
- };
209
-
210
-
211
- /*!
212
- * Hybrid graph representation for transitive relations
213
- */
214
- class HybridData
215
- {
216
- public:
217
- struct TreeNode
218
- {
219
- NodeID id;
220
- std::unordered_set<TreeNode*> children;
221
-
222
- TreeNode(NodeID nId) : id(nId)
223
- {}
224
-
225
- ~TreeNode()
226
- {
227
- }
228
-
229
- inline bool operator==(const TreeNode& rhs) const
230
- {
231
- return id == rhs.id;
232
- }
233
-
234
- inline bool operator<(const TreeNode& rhs) const
235
- {
236
- return id < rhs.id;
237
- }
238
- };
239
-
240
-
241
- public:
242
- Map<NodeID, std::unordered_map<NodeID, TreeNode*>> indMap; // indMap[v][u] points to node v in tree(u)
243
-
244
- HybridData()
245
- {}
246
-
247
- ~HybridData()
248
- {
249
- for (auto iter1: indMap)
250
- {
251
- for (auto iter2: iter1.second)
252
- {
253
- delete iter2.second;
254
- iter2.second = NULL;
255
- }
256
- }
257
- }
258
-
259
- bool hasInd(NodeID src, NodeID dst)
260
- {
261
- auto it = indMap.find(dst);
262
- if (it == indMap.end())
263
- return false;
264
- return (it->second.find(src) != it->second.end());
265
- }
266
-
267
- /// Add a node dst to tree(src)
268
- TreeNode* addInd(NodeID src, NodeID dst)
269
- {
270
- auto resIns = indMap[dst].insert(std::make_pair(src, new TreeNode(dst)));
271
- if (resIns.second)
272
- return resIns.first->second;
273
- return nullptr;
274
- }
275
-
276
- /// Get the node dst in tree(src)
277
- TreeNode* getNode(NodeID src, NodeID dst)
278
- {
279
- return indMap[dst][src];
280
- }
281
-
282
- /// add v into desc(x) as a child of u
283
- void insertEdge(TreeNode* u, TreeNode* v)
284
- {
285
- u->children.insert(v);
286
- }
287
-
288
- void addArc(NodeID src, NodeID dst)
289
- {
290
- if (!hasInd(src, dst))
291
- {
292
- for (auto iter: indMap[src])
293
- {
294
- meld(iter.first, getNode(iter.first, src), getNode(dst, dst));
295
- }
296
- }
297
- }
298
-
299
- void meld(NodeID x, TreeNode* uNode, TreeNode* vNode)
300
- {
301
- TreeNode* newVNode = addInd(x, vNode->id);
302
- if (!newVNode)
303
- return;
304
-
305
- insertEdge(uNode, newVNode);
306
- for (TreeNode* vChild: vNode->children)
307
- {
308
- meld(x, newVNode, vChild);
309
- }
310
- }
311
- };
312
-
313
-
314
- } // end namespace SVF
315
-
316
- #endif
@@ -1,91 +0,0 @@
1
- //===----- CFLDataBuilder.h -- CFL Data Builder --------------//
2
- //
3
- // SVF: Static Value-Flow Analysis
4
- //
5
- // Copyright (C) <2013-> <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
- * CFLGraphBuilder.h
25
- *
26
- * Created on: Nov 6, 2022
27
- * Author: Pei Xu
28
- */
29
-
30
- #ifndef INCLUDE_CFL_CFLDATABUILDER_H_
31
- #define INCLUDE_CFL_CFLDATABUILDER_H_
32
-
33
- #include "CFL/CFLData.h"
34
- #include "Graphs/CFLGraph.h"
35
-
36
- namespace SVF
37
- {
38
-
39
- /*!
40
- * Build CFLData from CFL graph
41
-
42
- */
43
-
44
- class CFLDataBuilder
45
- {
46
- protected:
47
- CFLData* _cflData;
48
- CFLGraph* _graph;
49
-
50
- public:
51
- /// Constructor
52
- CFLDataBuilder(CFLGraph* cflgraph) : _cflData(NULL), _graph(cflgraph)
53
- {
54
- if (!_cflData)
55
- _cflData = new CFLData();
56
- }
57
-
58
- /// Destructor
59
- virtual ~CFLDataBuilder()
60
- {
61
- }
62
-
63
- CFLData* cflData()
64
- {
65
- return _cflData;
66
- }
67
-
68
- //CFL data operations
69
- //@{
70
- virtual bool addEdge(const NodeID srcId, const NodeID dstId, const Label ty)
71
- {
72
- return cflData()->addEdge(srcId, dstId, ty);
73
- }
74
-
75
- virtual NodeBS addEdges(const NodeID srcId, const NodeBS& dstData, const Label ty)
76
- {
77
- return cflData()->addEdges(srcId, dstData, ty);
78
- }
79
- //@}
80
- CFLData* build()
81
- {
82
- for (CFLEdge* edge: _graph->getCFLEdges())
83
- addEdge(edge->getSrcID(), edge->getDstID(), edge->getEdgeKind());
84
- return cflData();
85
- }
86
-
87
-
88
- };
89
- }// SVF
90
-
91
- #endif /* INCLUDE_CFL_CFLGRAPHBUILDER_H_*/