Static Value-Flow Analysis
Loading...
Searching...
No Matches
CFLSolver.cpp
Go to the documentation of this file.
1//===----- CFLSolver.cpp -- Context-free language reachability solver--------------//
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 Affero 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 Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23/*
24 * CFLSolver.cpp
25 *
26 * Created on: March 5, 2022
27 * Author: Yulei Sui
28 */
29
30#include "CFL/CFLSolver.h"
31
32using namespace SVF;
33
34double CFLSolver::numOfChecks = 0;
35
37{
38 for(auto it = graph->begin(); it!= graph->end(); it++)
39 {
40 for(const CFLEdge* edge : (*it).second->getOutEdges())
41 {
43 }
44 }
45
48 for(const Production& prod : grammar->getEpsilonProds())
49 {
50 for(auto it = graph->begin(); it!= graph->end(); it++)
51 {
53 CFLNode* i = (*it).second;
54 if(const CFLEdge* edge = graph->addCFLEdge(i, i, X))
55 {
57 }
58 }
59 }
60}
61
63{
64 CFLNode* i = Y_edge->getSrcNode();
65 CFLNode* j = Y_edge->getDstNode();
66
69 Symbol Y = Y_edge->getEdgeKind();
72 {
75 if(const CFLEdge* newEdge = graph->addCFLEdge(i, j, X))
76 {
78 }
79 }
80
86 {
88 for(const CFLEdge* Z_edge : j->getOutEdgeWithTy(grammar->getSecondRHSSymbol(prod)))
89 {
90 CFLNode* k = Z_edge->getDstNode();
92 if(const CFLEdge* newEdge = graph->addCFLEdge(i, k, X))
93 {
95 }
96 }
97 }
98
104 {
106 for(const CFLEdge* Z_edge : i->getInEdgeWithTy(grammar->getFirstRHSSymbol(prod)))
107 {
108 CFLNode* k = Z_edge->getSrcNode();
109 numOfChecks++;
110 if(const CFLEdge* newEdge = graph->addCFLEdge(k, j, X))
111 {
113 }
114 }
115 }
116}
117
118
120{
122 initialize();
123
124 while(!isWorklistEmpty())
125 {
127 const CFLEdge* Y_edge = popFromWorklist();
129 }
130}
131
133{
134 for (CFLEdge* edge: graph->getCFLEdges())
135 addEdge(edge->getSrcID(), edge->getDstID(), edge->getEdgeKind());
136}
137
139{
140 CFLNode* i = Y_edge->getSrcNode();
141 CFLNode* j = Y_edge->getDstNode();
142
145 Symbol Y = Y_edge->getEdgeKind();
148 {
150 numOfChecks++;
151 if (addEdge(i->getId(), j->getId(), X))
152 {
153 const CFLEdge* newEdge = graph->addCFLEdge(Y_edge->getSrcNode(), Y_edge->getDstNode(), X);
155 }
156
157 }
158
164 {
167 numOfChecks += getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)].count();
168 for (NodeID diffDst: diffDsts)
169 {
172 }
173 }
174
180 {
182 NodeBS diffSrcs = addEdges(getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)], j->getId(), X);
183 numOfChecks += getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)].count();
184 for (NodeID diffSrc: diffSrcs)
185 {
188 }
189 }
190}
191
193{
194 for(auto edge : graph->getCFLEdges())
195 {
197 }
198
201 for(const Production& prod : grammar->getEpsilonProds())
202 {
203 for(auto IDMap : getSuccMap())
204 {
206 if (addEdge(IDMap.first, IDMap.first, X))
207 {
208 CFLNode* i = graph->getGNode(IDMap.first);
209 const CFLEdge* newEdge = graph->addCFLEdge(i, i, X);
211 }
212 }
213 }
214}
215
217{
218 CFLNode* i = Y_edge->getSrcNode();
219 CFLNode* j = Y_edge->getDstNode();
220
223 Symbol Y = Y_edge->getEdgeKind();
226 {
228 numOfChecks++;
229 if (addEdge(i->getId(), j->getId(), X))
230 {
231 const CFLEdge* newEdge = graph->addCFLEdge(Y_edge->getSrcNode(), Y_edge->getDstNode(), X);
233 }
234
235 }
236
242 {
244 {
245 addArc(i->getId(), j->getId());
246 }
247 else
248 {
251 numOfChecks += getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)].count();
252 for (NodeID diffDst: diffDsts)
253 {
256 }
257 }
258 }
259
265 {
267 {
268 addArc(i->getId(), j->getId());
269 }
270 else
271 {
273 NodeBS diffSrcs = addEdges(getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)], j->getId(), X);
274 numOfChecks += getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)].count();
275 for (NodeID diffSrc: diffSrcs)
276 {
279 }
280 }
281 }
282}
283
285{
286 for(auto edge : graph->getCFLEdges())
287 {
289 }
290
291 // init hybrid dataset
292 for (auto it = graph->begin(); it != graph->end(); ++it)
293 {
294 NodeID nId = it->first;
295 addInd_h(nId, nId);
296 }
297
299 for(const Production& prod : grammar->getEpsilonProds())
300 {
301 for(auto IDMap : getSuccMap())
302 {
304 if (addEdge(IDMap.first, IDMap.first, X))
305 {
306 CFLNode* i = graph->getGNode(IDMap.first);
307 const CFLEdge* newEdge = graph->addCFLEdge(i, i, X);
309 }
310 }
311 }
312}
313
315{
316 if(hasEdge(src, dst, grammar->strToSymbol("F")))
317 return;
318
319 for (auto& iter: indMap[src])
320 {
321 meld(iter.first, getNode_h(iter.first, src), getNode_h(dst, dst));
322 }
323}
324
325
327{
328 numOfChecks++;
329
331 if (!newVNode)
332 return;
333
335 for (TreeNode* vChild: vNode->children)
336 {
338 }
339}
340
342{
343 auto it = indMap.find(dst);
344 if (it == indMap.end())
345 return false;
346 return (it->second.find(src) != it->second.end());
347}
348
350{
351 TreeNode* newNode = new TreeNode(dst);
352 auto resIns = indMap[dst].insert(std::make_pair(src, newNode));
353 if (resIns.second)
354 return resIns.first->second;
355 delete newNode;
356 return nullptr;
357}
358
360{
361 if (!hasInd_h(src, dst))
362 {
363 for (auto iter: indMap[src])
364 {
365 meld_h(iter.first, getNode_h(iter.first, src), getNode_h(dst, dst));
366 }
367 }
368}
369
371{
373 if (!newVNode)
374 return;
375
377 for (TreeNode* vChild: vNode->children)
378 {
380 }
381}
const Symbol & getFirstRHSSymbol(const Production &prod) const
Definition CFGrammar.h:373
const Productions & getProdsFromFirstRHS(const Symbol sym) const
Definition CFGrammar.h:353
const Symbol & getSecondRHSSymbol(const Production &prod) const
Definition CFGrammar.h:378
Productions & getEpsilonProds()
Definition CFGrammar.h:308
const bool hasProdsFromFirstRHS(const Symbol sym) const
Definition CFGrammar.h:328
const bool hasProdsFromSecondRHS(const Symbol sym) const
Definition CFGrammar.h:340
const Symbol & getLHSSymbol(const Production &prod) const
Definition CFGrammar.h:368
const Productions & getProdsFromSecondRHS(const Symbol sym) const
Definition CFGrammar.h:360
const Productions & getProdsFromSingleRHS(const Symbol sym) const
Definition CFGrammar.h:346
const bool hasProdsFromSingleRHS(const Symbol sym) const
Definition CFGrammar.h:334
const CFLEdgeSet & getCFLEdges() const
Definition CFLGraph.h:198
virtual const CFLEdge * addCFLEdge(CFLNode *src, CFLNode *dst, CFLEdge::GEdgeFlag label)
Definition CFLGraph.cpp:47
virtual void solve()
Start solving.
static double numOfChecks
Definition CFLSolver.h:52
virtual void processCFLEdge(const CFLEdge *Y_edge)
Process CFLEdge.
Definition CFLSolver.cpp:62
virtual void initialize()
Initialize worklist.
Definition CFLSolver.cpp:36
CFGrammar::Production Production
Definition CFLSolver.h:49
CFGrammar * grammar
Definition CFLSolver.h:109
virtual bool pushIntoWorklist(const CFLEdge *item)
Definition CFLSolver.h:84
virtual bool isWorklistEmpty()
Definition CFLSolver.h:88
const CFLEdge * popFromWorklist()
Worklist operations.
Definition CFLSolver.h:96
CFLGraph * graph
Definition CFLSolver.h:108
iterator begin()
Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
Symbol strToSymbol(const std::string str) const
Definition CFGrammar.cpp:74
TreeNode * getNode_h(NodeID src, NodeID dst)
Get the node dst in tree(src)
Definition CFLSolver.h:331
void insertEdge_h(TreeNode *u, TreeNode *v)
add v into desc(x) as a child of u
Definition CFLSolver.h:337
virtual void initialize()
Initialize worklist.
void meld(NodeID x, TreeNode *uNode, TreeNode *vNode)
void meld_h(NodeID x, TreeNode *uNode, TreeNode *vNode)
bool hasInd_h(NodeID src, NodeID dst)
void addArc_h(NodeID src, NodeID dst)
void addArc(NodeID src, NodeID dst)
TreeNode * addInd_h(NodeID src, NodeID dst)
Add a node dst to tree(src)
Map< NodeID, std::unordered_map< NodeID, TreeNode * > > indMap
Definition CFLSolver.h:323
virtual void processCFLEdge(const CFLEdge *Y_edge)
Process CFLEdge.
bool hasEdge(const NodeID src, const NodeID dst, const Label ty)
find src -> find src[ty] -> find dst in set
Definition CFLSolver.h:248
DataMap & getPredMap()
Definition CFLSolver.h:188
virtual void processCFLEdge(const CFLEdge *Y_edge)
Process CFLEdge.
NodeBS addEdges(const NodeID src, const NodeBS &dstData, const Label ty)
add edges and return the set of added edges (dst) for src
Definition CFLSolver.h:222
bool addEdge(const NodeID src, const NodeID dst, const Label ty)
Definition CFLSolver.h:215
DataMap & getSuccMap()
Definition CFLSolver.h:183
virtual void initialize()
Initialize worklist.
virtual void buildCFLData()
Init CFLData.
for isBitcode
Definition BasicTypes.h:68
u32_t NodeID
Definition GeneralType.h:55
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74