svf-tools 1.0.731 → 1.0.732
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/CFGNormalizer.h +1 -1
- package/svf/include/CFL/CFLAlias.h +2 -2
- package/svf/include/CFL/CFLBase.h +3 -0
- package/svf/include/CFL/CFLGramGraphChecker.h +10 -10
- package/svf/include/CFL/CFLGrammar.h +29 -29
- package/svf/include/CFL/CFLGraphBuilder.h +68 -44
- package/svf/include/CFL/CFLVF.h +3 -0
- package/svf/include/Util/Options.h +1 -0
- package/svf/include/Util/SVFUtil.h +12 -5
- package/svf/lib/CFL/CFGNormalizer.cpp +26 -26
- package/svf/lib/CFL/CFLAlias.cpp +3 -0
- package/svf/lib/CFL/CFLBase.cpp +23 -2
- package/svf/lib/CFL/CFLGrammar.cpp +19 -19
- package/svf/lib/CFL/CFLGraphBuilder.cpp +153 -178
- package/svf/lib/CFL/CFLSolver.cpp +3 -3
- package/svf/lib/CFL/CFLVF.cpp +18 -0
- package/svf/lib/Util/Options.cpp +6 -0
- package/svf-llvm/tools/CFL/cfl.cpp +14 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.732",
|
|
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": {
|
|
@@ -56,7 +56,7 @@ public:
|
|
|
56
56
|
CFLGrammar* normalize(GrammarBase *generalGrammar);
|
|
57
57
|
|
|
58
58
|
/// Expand every variable attribute in rawProductions of grammarbase
|
|
59
|
-
CFLGrammar* fillAttribute(CFLGrammar *grammar, const Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>&
|
|
59
|
+
CFLGrammar* fillAttribute(CFLGrammar *grammar, const Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>& kindToAttrsMap);
|
|
60
60
|
|
|
61
61
|
private:
|
|
62
62
|
/// Add nonterminal to tranfer long rules to binary rules
|
|
@@ -112,8 +112,8 @@ public:
|
|
|
112
112
|
{
|
|
113
113
|
return false;
|
|
114
114
|
}
|
|
115
|
-
CFLGrammar::Kind copyKind = grammar->
|
|
116
|
-
CFLGrammar::Kind copybarKind = grammar->
|
|
115
|
+
CFLGrammar::Kind copyKind = grammar->strToKind("copy");
|
|
116
|
+
CFLGrammar::Kind copybarKind = grammar->strToKind("copybar");
|
|
117
117
|
solver->pushIntoWorklist(graph->addCFLEdge(graph->getGNode(src),graph->getGNode(dst), copyKind));
|
|
118
118
|
solver->pushIntoWorklist(graph->addCFLEdge(graph->getGNode(dst),graph->getGNode(src), copybarKind));
|
|
119
119
|
return true;
|
|
@@ -42,29 +42,29 @@ public:
|
|
|
42
42
|
/// Check all kinds in grammar in graphBuilder with the same label
|
|
43
43
|
for(auto pairV : grammar->getTerminals())
|
|
44
44
|
{
|
|
45
|
-
if (graphBuilder->
|
|
45
|
+
if (graphBuilder->getLabelToKindMap().find(pairV.first) != graphBuilder->getLabelToKindMap().end())
|
|
46
46
|
{
|
|
47
|
-
assert(graphBuilder->
|
|
48
|
-
assert(graphBuilder->
|
|
47
|
+
assert(graphBuilder->getLabelToKindMap()[pairV.first] == pairV.second);
|
|
48
|
+
assert(graphBuilder->getKindToLabelMap()[pairV.second] == pairV.first);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
for(auto pairV : grammar->getNonterminals())
|
|
53
53
|
{
|
|
54
|
-
if (graphBuilder->
|
|
54
|
+
if (graphBuilder->getLabelToKindMap().find(pairV.first) != graphBuilder->getLabelToKindMap().end())
|
|
55
55
|
{
|
|
56
|
-
assert(graphBuilder->
|
|
57
|
-
assert(graphBuilder->
|
|
56
|
+
assert(graphBuilder->getLabelToKindMap()[pairV.first] == pairV.second);
|
|
57
|
+
assert(graphBuilder->getKindToLabelMap()[pairV.second] == pairV.first);
|
|
58
58
|
}
|
|
59
59
|
else
|
|
60
60
|
{
|
|
61
|
-
graphBuilder->
|
|
62
|
-
graphBuilder->
|
|
61
|
+
graphBuilder->getLabelToKindMap().insert(std::make_pair (pairV.first,pairV.second));
|
|
62
|
+
graphBuilder->getKindToLabelMap().insert(std::make_pair (pairV.second, pairV.first));
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
/// Get
|
|
67
|
-
grammar->
|
|
66
|
+
/// Get KindToAttrs Map from Graph to Grammar
|
|
67
|
+
grammar->setKindToAttrsMap(graphBuilder->getKindToAttrsMap());
|
|
68
68
|
graph->startKind = grammar->getStartKind();
|
|
69
69
|
}
|
|
70
70
|
};
|
|
@@ -192,9 +192,9 @@ public:
|
|
|
192
192
|
return this->rawProductions;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
inline const Map<Kind, Set<Attribute>>&
|
|
195
|
+
inline const Map<Kind, Set<Attribute>>& getKindToAttrsMap() const
|
|
196
196
|
{
|
|
197
|
-
return this->
|
|
197
|
+
return this->kindToAttrsMap;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
inline Kind getTotalKind()
|
|
@@ -223,17 +223,17 @@ public:
|
|
|
223
223
|
|
|
224
224
|
void setRawProductions(SymbolMap<Symbol, Productions>& rawProductions);
|
|
225
225
|
|
|
226
|
-
void
|
|
226
|
+
void setKindToAttrsMap(const Map<Kind, Set<Attribute>>& kindToAttrsMap);
|
|
227
227
|
|
|
228
228
|
void setAttributeKinds(const Set<Kind>& attributeKind);
|
|
229
229
|
|
|
230
|
-
Kind
|
|
230
|
+
Kind strToKind(std::string str) const;
|
|
231
231
|
|
|
232
|
-
Symbol
|
|
232
|
+
Symbol strToSymbol(const std::string str) const;
|
|
233
233
|
|
|
234
|
-
std::string
|
|
234
|
+
std::string kindToStr(Kind kind) const;
|
|
235
235
|
|
|
236
|
-
std::string
|
|
236
|
+
std::string symToStrDump(Symbol sym) const;
|
|
237
237
|
|
|
238
238
|
Symbol getSymbol(const Production& prod, u32_t pos)
|
|
239
239
|
{
|
|
@@ -282,7 +282,7 @@ private:
|
|
|
282
282
|
Map<std::string, Kind> terminals;
|
|
283
283
|
Map<std::string, Kind> EBNFSigns; /// Map contains Signs' String and associated Symbols
|
|
284
284
|
Set<Kind> attributeKinds;
|
|
285
|
-
Map<Kind, Set<Attribute>>
|
|
285
|
+
Map<Kind, Set<Attribute>> kindToAttrsMap;
|
|
286
286
|
SymbolMap<Symbol, Productions> rawProductions;
|
|
287
287
|
u32_t totalKind;
|
|
288
288
|
};
|
|
@@ -310,57 +310,57 @@ public:
|
|
|
310
310
|
return epsilonProds;
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
SymbolMap<Symbol, Productions>&
|
|
313
|
+
SymbolMap<Symbol, Productions>& getSingleRHSToProds()
|
|
314
314
|
{
|
|
315
|
-
return
|
|
315
|
+
return singleRHSToProds;
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
-
SymbolMap<Symbol, Productions>&
|
|
318
|
+
SymbolMap<Symbol, Productions>& getFirstRHSToProds()
|
|
319
319
|
{
|
|
320
|
-
return
|
|
320
|
+
return firstRHSToProds;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
-
SymbolMap<Symbol, Productions>&
|
|
323
|
+
SymbolMap<Symbol, Productions>& getSecondRHSToProds()
|
|
324
324
|
{
|
|
325
|
-
return
|
|
325
|
+
return secondRHSToProds;
|
|
326
326
|
}
|
|
327
327
|
|
|
328
328
|
const bool hasProdsFromFirstRHS(const Symbol sym) const
|
|
329
329
|
{
|
|
330
|
-
auto it =
|
|
331
|
-
return it!=
|
|
330
|
+
auto it = firstRHSToProds.find(sym);
|
|
331
|
+
return it!=firstRHSToProds.end();
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
const bool hasProdsFromSingleRHS(const Symbol sym) const
|
|
335
335
|
{
|
|
336
|
-
auto it =
|
|
337
|
-
return it!=
|
|
336
|
+
auto it = singleRHSToProds.find(sym);
|
|
337
|
+
return it!=singleRHSToProds.end();
|
|
338
338
|
}
|
|
339
339
|
|
|
340
340
|
const bool hasProdsFromSecondRHS(const Symbol sym) const
|
|
341
341
|
{
|
|
342
|
-
auto it =
|
|
343
|
-
return it!=
|
|
342
|
+
auto it = secondRHSToProds.find(sym);
|
|
343
|
+
return it!=secondRHSToProds.end();
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
const Productions& getProdsFromSingleRHS(const Symbol sym) const
|
|
347
347
|
{
|
|
348
|
-
auto it =
|
|
349
|
-
assert(it!=
|
|
348
|
+
auto it = singleRHSToProds.find(sym);
|
|
349
|
+
assert(it!=singleRHSToProds.end() && "production (X -> sym) not found for sym!!");
|
|
350
350
|
return it->second;
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
const Productions& getProdsFromFirstRHS(const Symbol sym) const
|
|
354
354
|
{
|
|
355
|
-
auto it =
|
|
356
|
-
assert(it!=
|
|
355
|
+
auto it = firstRHSToProds.find(sym);
|
|
356
|
+
assert(it!=firstRHSToProds.end() && "production (X -> sym Y ) not found for sym!!");
|
|
357
357
|
return it->second;
|
|
358
358
|
}
|
|
359
359
|
|
|
360
360
|
const Productions& getProdsFromSecondRHS(const Symbol sym) const
|
|
361
361
|
{
|
|
362
|
-
auto it =
|
|
363
|
-
assert(it!=
|
|
362
|
+
auto it = secondRHSToProds.find(sym);
|
|
363
|
+
assert(it!=secondRHSToProds.end() && "production (X -> Y sym) not found for sym!!");
|
|
364
364
|
return it->second;
|
|
365
365
|
}
|
|
366
366
|
|
|
@@ -392,9 +392,9 @@ public:
|
|
|
392
392
|
|
|
393
393
|
private:
|
|
394
394
|
SymbolSet<Production> epsilonProds;
|
|
395
|
-
SymbolMap<Symbol, Productions>
|
|
396
|
-
SymbolMap<Symbol, Productions>
|
|
397
|
-
SymbolMap<Symbol, Productions>
|
|
395
|
+
SymbolMap<Symbol, Productions> singleRHSToProds;
|
|
396
|
+
SymbolMap<Symbol, Productions> firstRHSToProds;
|
|
397
|
+
SymbolMap<Symbol, Productions> secondRHSToProds;
|
|
398
398
|
u32_t newTerminalSubscript;
|
|
399
399
|
};
|
|
400
400
|
|
|
@@ -37,27 +37,40 @@
|
|
|
37
37
|
namespace SVF
|
|
38
38
|
{
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
*
|
|
42
|
-
|
|
40
|
+
/**
|
|
41
|
+
* CFLGraphBuilder class is responsible for building CFL (Context-Free Language) graphs
|
|
42
|
+
* from text files or dot files or from memory graph.
|
|
43
43
|
*/
|
|
44
|
-
|
|
45
44
|
class CFLGraphBuilder
|
|
46
45
|
{
|
|
47
46
|
protected:
|
|
47
|
+
/// Define Kind(Not contain attribute) and Symbol(May contain attribute) as types derived from CFLGrammar
|
|
48
|
+
/// to numerically represent label
|
|
48
49
|
typedef CFLGrammar::Kind Kind;
|
|
49
50
|
typedef CFLGrammar::Symbol Symbol;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Map<
|
|
53
|
-
|
|
51
|
+
|
|
52
|
+
/// Maps to maintain mapping between labels and kinds
|
|
53
|
+
Map<std::string, Kind> labelToKindMap;
|
|
54
|
+
Map<Kind, std::string> kindToLabelMap;
|
|
55
|
+
|
|
56
|
+
/// Map to maintain attributes associated with each kind
|
|
57
|
+
Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>> kindToAttrsMap;
|
|
58
|
+
|
|
54
59
|
Kind current;
|
|
60
|
+
CFLGraph *cflGraph;
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
/// add attribute to kind2Attribute Map
|
|
62
|
+
/// Method to add an attribute to a specific kind
|
|
58
63
|
void addAttribute(CFLGrammar::Kind kind, CFLGrammar::Attribute attribute);
|
|
59
64
|
|
|
60
|
-
///
|
|
65
|
+
/// build label and kind connect from the grammar
|
|
66
|
+
void buildlabelToKindMap(GrammarBase *grammar);
|
|
67
|
+
|
|
68
|
+
/// add src and dst node from file
|
|
69
|
+
CFLNode* addGNode(u32_t NodeID);
|
|
70
|
+
|
|
71
|
+
public:
|
|
72
|
+
/// Method to build a CFL graph by copying nodes and edges from any graph
|
|
73
|
+
/// inherited from GenericGraph
|
|
61
74
|
template<class N, class E>
|
|
62
75
|
void build(GenericGraph<N,E>* graph, CFLGraph* cflGraph)
|
|
63
76
|
{
|
|
@@ -76,32 +89,32 @@ public:
|
|
|
76
89
|
}
|
|
77
90
|
}
|
|
78
91
|
|
|
79
|
-
///
|
|
92
|
+
/// Method to build a bidirectional CFL graph by copying nodes and edges
|
|
93
|
+
/// from any graph inherited from GenericGraph
|
|
80
94
|
template<class N, class E>
|
|
81
95
|
CFLGraph* buildBigraph(GenericGraph<N,E>* graph, Kind startKind, GrammarBase *grammar)
|
|
82
96
|
{
|
|
83
97
|
CFLGraph *cflGraph = new CFLGraph(startKind);
|
|
84
|
-
externMap = true;
|
|
85
98
|
for(auto pairV : grammar->getTerminals())
|
|
86
99
|
{
|
|
87
|
-
if(
|
|
100
|
+
if(labelToKindMap.find(pairV.first) == labelToKindMap.end())
|
|
88
101
|
{
|
|
89
|
-
|
|
102
|
+
labelToKindMap.insert(pairV);
|
|
90
103
|
}
|
|
91
|
-
if(
|
|
104
|
+
if(kindToLabelMap.find(pairV.second) == kindToLabelMap.end())
|
|
92
105
|
{
|
|
93
|
-
|
|
106
|
+
kindToLabelMap.insert(make_pair(pairV.second, pairV.first));
|
|
94
107
|
}
|
|
95
108
|
}
|
|
96
109
|
for(auto pairV : grammar->getNonterminals())
|
|
97
110
|
{
|
|
98
|
-
if(
|
|
111
|
+
if(labelToKindMap.find(pairV.first) == labelToKindMap.end())
|
|
99
112
|
{
|
|
100
|
-
|
|
113
|
+
labelToKindMap.insert(pairV);
|
|
101
114
|
}
|
|
102
|
-
if(
|
|
115
|
+
if(kindToLabelMap.find(pairV.second) == kindToLabelMap.end())
|
|
103
116
|
{
|
|
104
|
-
|
|
117
|
+
kindToLabelMap.insert(make_pair(pairV.second, pairV.first));
|
|
105
118
|
}
|
|
106
119
|
}
|
|
107
120
|
for(auto it = graph->begin(); it!= graph->end(); it++)
|
|
@@ -116,78 +129,89 @@ public:
|
|
|
116
129
|
{
|
|
117
130
|
CFLGrammar::Kind edgeLabel = edge->getEdgeKind();
|
|
118
131
|
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel);
|
|
119
|
-
std::string key =
|
|
132
|
+
std::string key = kindToLabelMap[edge->getEdgeKind()];
|
|
120
133
|
key.append("bar");
|
|
121
|
-
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()),
|
|
134
|
+
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), labelToKindMap[key]);
|
|
122
135
|
}
|
|
123
136
|
}
|
|
124
137
|
return cflGraph;
|
|
125
138
|
}
|
|
126
139
|
|
|
127
|
-
///
|
|
128
|
-
void build(std::string filename, CFLGraph* cflGraph);
|
|
129
|
-
|
|
130
|
-
/// Build graph from Dot
|
|
140
|
+
/// Method to build a CFL graph from a Dot file
|
|
131
141
|
CFLGraph *buildFromDot(std::string filename, GrammarBase *grammar);
|
|
132
142
|
|
|
133
|
-
|
|
143
|
+
/// Method to build a CFL graph from a Text file
|
|
144
|
+
CFLGraph* buildFromTextFile(std::string fileName, GrammarBase *grammar);
|
|
145
|
+
|
|
146
|
+
/// @{
|
|
147
|
+
/// Getter methods for accessing class variables
|
|
148
|
+
|
|
149
|
+
/// Returns a reference to the map that associates string labels with their corresponding Kind
|
|
150
|
+
Map<std::string, Kind>& getLabelToKindMap()
|
|
134
151
|
{
|
|
135
|
-
return this->
|
|
152
|
+
return this->labelToKindMap;
|
|
136
153
|
}
|
|
137
154
|
|
|
138
|
-
|
|
155
|
+
/// Returns a reference to the map that associates Kinds with their corresponding string labels
|
|
156
|
+
Map<Kind, std::string>& getKindToLabelMap()
|
|
139
157
|
{
|
|
140
|
-
return this->
|
|
158
|
+
return this->kindToLabelMap;
|
|
141
159
|
}
|
|
142
160
|
|
|
143
|
-
|
|
161
|
+
/// Returns a reference to the map that associates Kinds with their corresponding attributes
|
|
162
|
+
Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>& getKindToAttrsMap()
|
|
144
163
|
{
|
|
145
|
-
return this->
|
|
164
|
+
return this->kindToAttrsMap;
|
|
146
165
|
}
|
|
147
166
|
|
|
148
|
-
|
|
167
|
+
/// @}
|
|
149
168
|
};
|
|
150
169
|
|
|
170
|
+
/// AliasCFLGraphBuilder: a CFLGraphBuilder specialized for handling aliasing
|
|
151
171
|
class AliasCFLGraphBuilder : public CFLGraphBuilder
|
|
152
172
|
{
|
|
153
173
|
public:
|
|
154
|
-
///
|
|
174
|
+
/// Builds a bidirectional CFL graph by copying nodes and edges from a const graph that inherits from GenericGraph
|
|
155
175
|
CFLGraph* buildBigraph(ConstraintGraph *graph, Kind startKind, GrammarBase *grammar);
|
|
156
176
|
|
|
157
|
-
///
|
|
158
|
-
///
|
|
177
|
+
/// Builds a bidirectional CFL graph by copying nodes and edges from any graph that inherits from GenericGraph
|
|
178
|
+
/// Transfers Load and Store to copy edge and address edge to construct PEG style CFLGraph
|
|
159
179
|
CFLGraph* buildBiPEGgraph(ConstraintGraph *graph, Kind startKind, GrammarBase *grammar, SVFIR* pag);
|
|
160
180
|
|
|
161
181
|
private:
|
|
182
|
+
/// Connects VGep (Variable GEP)
|
|
162
183
|
void connectVGep(CFLGraph *cflGraph, ConstraintGraph *graph, ConstraintNode *src, ConstraintNode *dst, u32_t level, SVFIR* pag);
|
|
163
184
|
|
|
164
|
-
///
|
|
185
|
+
/// Handles edges, with the exception of the GEP
|
|
165
186
|
void addBiCFLEdge(CFLGraph *cflGraph, ConstraintNode* src, ConstraintNode* dst, CFLGrammar::Kind label);
|
|
166
187
|
|
|
167
|
-
///
|
|
188
|
+
/// Adds bidirectional GEP edges with attributes
|
|
168
189
|
void addBiGepCFLEdge(CFLGraph *cflGraph, ConstraintNode* src, ConstraintNode* dst, CFLGrammar::Attribute attri);
|
|
169
190
|
};
|
|
170
191
|
|
|
192
|
+
/// VFCFLGraphBuilder: a CFLGraphBuilder specialized for handling value-flow
|
|
171
193
|
class VFCFLGraphBuilder : public CFLGraphBuilder
|
|
172
194
|
{
|
|
173
195
|
public:
|
|
174
|
-
///
|
|
196
|
+
/// Builds a bidirectional CFL graph by copying nodes and edges from a const graph that inherits from SVFG
|
|
175
197
|
CFLGraph* buildBigraph(SVFG *graph, Kind startKind, GrammarBase *grammar);
|
|
176
198
|
|
|
177
|
-
///
|
|
178
|
-
///
|
|
199
|
+
/// Builds a bidirectional CFL graph by copying nodes and edges from any graph that inherits from GenericGraph
|
|
200
|
+
/// Transfers Load and Store to copy edge and address edge to construct PEG style CFLGraph
|
|
179
201
|
CFLGraph* buildBiPEGgraph(ConstraintGraph *graph, Kind startKind, GrammarBase *grammar, SVFIR* pag);
|
|
180
202
|
|
|
181
203
|
private:
|
|
204
|
+
/// Connects VGep (Variable GEP)
|
|
182
205
|
void connectVGep(CFLGraph *cflGraph, ConstraintGraph *graph, ConstraintNode *src, ConstraintNode *dst, u32_t level, SVFIR* pag);
|
|
183
206
|
|
|
184
|
-
///
|
|
207
|
+
/// Handles edges, with the exception of the GEP
|
|
185
208
|
void addBiCFLEdge(CFLGraph *cflGraph, ConstraintNode* src, ConstraintNode* dst, CFLGrammar::Kind label);
|
|
186
209
|
|
|
187
|
-
///
|
|
210
|
+
/// Adds bidirectional GEP edges with attributes
|
|
188
211
|
void addBiGepCFLEdge(CFLGraph *cflGraph, ConstraintNode* src, ConstraintNode* dst, CFLGrammar::Attribute attri);
|
|
189
212
|
};
|
|
190
213
|
|
|
214
|
+
|
|
191
215
|
}// SVF
|
|
192
216
|
|
|
193
217
|
#endif /* INCLUDE_CFL_CFLGRAPHBUILDER_H_*/
|
package/svf/include/CFL/CFLVF.h
CHANGED
|
@@ -215,17 +215,24 @@ inline CallSite getSVFCallSite(const SVFValue* value)
|
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
/// Split into two substrings around the first occurrence of a separator string.
|
|
218
|
-
inline std::vector<std::string> split(const std::string& s, char
|
|
218
|
+
inline std::vector<std::string> split(const std::string& s, char separator)
|
|
219
219
|
{
|
|
220
220
|
std::vector<std::string> output;
|
|
221
221
|
std::string::size_type prev_pos = 0, pos = 0;
|
|
222
|
-
while((pos = s.find(
|
|
222
|
+
while ((pos = s.find(separator, pos)) != std::string::npos)
|
|
223
223
|
{
|
|
224
|
-
std::string substring(
|
|
225
|
-
|
|
224
|
+
std::string substring(s.substr(prev_pos, pos - prev_pos));
|
|
225
|
+
if (!substring.empty())
|
|
226
|
+
{
|
|
227
|
+
output.push_back(substring);
|
|
228
|
+
}
|
|
226
229
|
prev_pos = ++pos;
|
|
227
230
|
}
|
|
228
|
-
|
|
231
|
+
std::string lastSubstring(s.substr(prev_pos, pos - prev_pos));
|
|
232
|
+
if (!lastSubstring.empty())
|
|
233
|
+
{
|
|
234
|
+
output.push_back(lastSubstring);
|
|
235
|
+
}
|
|
229
236
|
return output;
|
|
230
237
|
}
|
|
231
238
|
|
|
@@ -48,21 +48,21 @@ CFLGrammar* CFGNormalizer::normalize(GrammarBase *generalGrammar)
|
|
|
48
48
|
grammar->setEBNFSigns(generalGrammar->getEBNFSigns());
|
|
49
49
|
grammar->setTotalKind(generalGrammar->getTotalKind());
|
|
50
50
|
grammar->setAttributeKinds(generalGrammar->getAttrSyms());
|
|
51
|
-
grammar->
|
|
51
|
+
grammar->setKindToAttrsMap(generalGrammar->getKindToAttrsMap());
|
|
52
52
|
grammar->setRawProductions(generalGrammar->getRawProductions());
|
|
53
53
|
barReplace(grammar);
|
|
54
54
|
ebnfSignReplace('*', grammar);
|
|
55
55
|
ebnfSignReplace('?', grammar);
|
|
56
56
|
ebnf_bin(grammar);
|
|
57
|
-
fillAttribute(grammar, grammar->
|
|
57
|
+
fillAttribute(grammar, grammar->getKindToAttrsMap());
|
|
58
58
|
return grammar;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
CFLGrammar* CFGNormalizer::fillAttribute(CFLGrammar *grammar, const Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>&
|
|
62
|
+
CFLGrammar* CFGNormalizer::fillAttribute(CFLGrammar *grammar, const Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>& kindToAttrsMap)
|
|
63
63
|
{
|
|
64
64
|
NodeSet nodeSet = {};
|
|
65
|
-
for (auto pair:
|
|
65
|
+
for (auto pair: kindToAttrsMap)
|
|
66
66
|
{
|
|
67
67
|
for (auto attri: pair.second)
|
|
68
68
|
{
|
|
@@ -245,7 +245,7 @@ void CFGNormalizer::getFilledProductions(GrammarBase::Production &prod, const No
|
|
|
245
245
|
normalProds.insert(currentProduction);
|
|
246
246
|
continue;
|
|
247
247
|
}
|
|
248
|
-
//*(
|
|
248
|
+
//*(kindToAttriMap.find(baseKind));
|
|
249
249
|
//for (auto attribute : nodeSet.second)
|
|
250
250
|
for (auto attribute : nodeSet)
|
|
251
251
|
{
|
|
@@ -284,7 +284,7 @@ int CFGNormalizer::ebnfBracketMatch(GrammarBase::Production &prod, int i, CFLGra
|
|
|
284
284
|
int index = i;
|
|
285
285
|
while (index >= 0)
|
|
286
286
|
{
|
|
287
|
-
if (grammar->
|
|
287
|
+
if (grammar->kindToStr(prod[index].kind) == "(")
|
|
288
288
|
{
|
|
289
289
|
return index;
|
|
290
290
|
}
|
|
@@ -305,7 +305,7 @@ void CFGNormalizer::barReplace(CFLGrammar *grammar)
|
|
|
305
305
|
size_t j = 1;
|
|
306
306
|
while (i < ebnfProduction.size())
|
|
307
307
|
{
|
|
308
|
-
if (grammar->
|
|
308
|
+
if (grammar->kindToStr(ebnfProduction[i].kind) == "|")
|
|
309
309
|
{
|
|
310
310
|
GrammarBase::Production tempPro(ebnfProduction.begin()+j, ebnfProduction.begin()+i);
|
|
311
311
|
tempPro.insert(tempPro.begin(), symbolToProductionsPair.first );
|
|
@@ -339,11 +339,11 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFLGrammar *grammar)
|
|
|
339
339
|
while (i < ebnfProduction.size())
|
|
340
340
|
{
|
|
341
341
|
s32_t signGroupStart = -1;
|
|
342
|
-
if (grammar->
|
|
342
|
+
if (grammar->kindToStr(ebnfProduction[i].kind) == std::string(1, sign))
|
|
343
343
|
{
|
|
344
344
|
/// If sign assoicate wihout group e.i with single symble
|
|
345
345
|
assert(i != 1 && "sign in grammar associate with no symbol");
|
|
346
|
-
if (grammar->
|
|
346
|
+
if (grammar->kindToStr(ebnfProduction[i - 1].kind) != std::string(1, ')'))
|
|
347
347
|
{
|
|
348
348
|
signGroupStart = i - 1;
|
|
349
349
|
}
|
|
@@ -355,20 +355,20 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFLGrammar *grammar)
|
|
|
355
355
|
std::string groupString = "";
|
|
356
356
|
for (size_t j = signGroupStart; j < i; j++)
|
|
357
357
|
{
|
|
358
|
-
groupString.append(grammar->
|
|
358
|
+
groupString.append(grammar->kindToStr(ebnfProduction[j].kind));
|
|
359
359
|
groupString.append(" ");
|
|
360
360
|
}
|
|
361
|
-
groupString.append(grammar->
|
|
361
|
+
groupString.append(grammar->kindToStr(ebnfProduction[i].kind));
|
|
362
362
|
if (newProductions.find(groupString) != newProductions.end())
|
|
363
363
|
{
|
|
364
364
|
productions.erase(ebnfProduction);
|
|
365
365
|
ebnfProduction.erase(ebnfProduction.begin() + signGroupStart, ebnfProduction.begin() + i + 1);
|
|
366
|
-
ebnfProduction.insert(ebnfProduction.begin() + signGroupStart, grammar->
|
|
366
|
+
ebnfProduction.insert(ebnfProduction.begin() + signGroupStart, grammar->strToSymbol(newProductions[groupString]));
|
|
367
367
|
productions.insert(ebnfProduction);
|
|
368
368
|
}
|
|
369
369
|
else if ( (signGroupStart == 1) && (i == ebnfProduction.size() -1))
|
|
370
370
|
{
|
|
371
|
-
newProductions[groupString] = grammar->
|
|
371
|
+
newProductions[groupString] = grammar->kindToStr(ebnfProduction[0].kind);
|
|
372
372
|
productions.erase(ebnfProduction);
|
|
373
373
|
ebnfProduction.erase(ebnfProduction.begin() + signGroupStart, ebnfProduction.begin() + i + 1);
|
|
374
374
|
|
|
@@ -398,10 +398,10 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFLGrammar *grammar)
|
|
|
398
398
|
{
|
|
399
399
|
/// For Both * and ? need to insert epsilon rule
|
|
400
400
|
std::string new_nonterminal = rep.second;
|
|
401
|
-
GrammarBase::Production temp_list = {grammar->
|
|
402
|
-
grammar->getRawProductions()[grammar->
|
|
401
|
+
GrammarBase::Production temp_list = {grammar->strToSymbol(new_nonterminal), grammar->strToSymbol("epsilon")};
|
|
402
|
+
grammar->getRawProductions()[grammar->strToSymbol(new_nonterminal)].insert(temp_list);
|
|
403
403
|
/// insert second rule for '*' X -> X E for '+' X -> E
|
|
404
|
-
temp_list = {grammar->
|
|
404
|
+
temp_list = {grammar->strToSymbol(new_nonterminal)};
|
|
405
405
|
if (sign == '*' || sign == '?')
|
|
406
406
|
{
|
|
407
407
|
/// Insert Back the Group
|
|
@@ -412,18 +412,18 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFLGrammar *grammar)
|
|
|
412
412
|
{
|
|
413
413
|
for (auto &word : normalProd)
|
|
414
414
|
{
|
|
415
|
-
if (word != grammar->
|
|
415
|
+
if (word != grammar->strToSymbol("*") && word != grammar->strToSymbol("(") && word != grammar->strToSymbol(")"))
|
|
416
416
|
{
|
|
417
417
|
withoutSign.push_back(word);
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
|
-
withoutSign.push_back(grammar->
|
|
420
|
+
withoutSign.push_back(grammar->strToSymbol(rep.second));
|
|
421
421
|
}
|
|
422
422
|
if (sign == '?')
|
|
423
423
|
{
|
|
424
424
|
for (auto &word : normalProd)
|
|
425
425
|
{
|
|
426
|
-
if (word != grammar->
|
|
426
|
+
if (word != grammar->strToSymbol("?") && word != grammar->strToSymbol("(") && word != grammar->strToSymbol(")"))
|
|
427
427
|
{
|
|
428
428
|
withoutSign.push_back(word);
|
|
429
429
|
}
|
|
@@ -431,7 +431,7 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFLGrammar *grammar)
|
|
|
431
431
|
}
|
|
432
432
|
temp_list.insert(temp_list.end(), withoutSign.begin(), withoutSign.end());
|
|
433
433
|
}
|
|
434
|
-
grammar->getRawProductions()[grammar->
|
|
434
|
+
grammar->getRawProductions()[grammar->strToSymbol(new_nonterminal)].insert(temp_list);
|
|
435
435
|
}
|
|
436
436
|
}
|
|
437
437
|
|
|
@@ -449,9 +449,9 @@ void CFGNormalizer::strTrans(std::string LHS, CFLGrammar *grammar, GrammarBase::
|
|
|
449
449
|
{
|
|
450
450
|
word = LHS.substr(0, pos);
|
|
451
451
|
LHS.erase(0, pos + delimiter.length());
|
|
452
|
-
normalProd.push_back(grammar->
|
|
452
|
+
normalProd.push_back(grammar->strToSymbol(word));
|
|
453
453
|
}
|
|
454
|
-
normalProd.push_back(grammar->
|
|
454
|
+
normalProd.push_back(grammar->strToSymbol(LHS));
|
|
455
455
|
}
|
|
456
456
|
|
|
457
457
|
GrammarBase::Symbol CFGNormalizer::check_head(GrammarBase::SymbolMap<GrammarBase::Symbol, GrammarBase::Productions> &grammar, GrammarBase::Production &rule)
|
|
@@ -475,7 +475,7 @@ void CFGNormalizer::insertToCFLGrammar(CFLGrammar *grammar, GrammarBase::Product
|
|
|
475
475
|
{
|
|
476
476
|
if (prod.size() == 2)
|
|
477
477
|
{
|
|
478
|
-
if ((std::find(prod.begin(), prod.end(), grammar->
|
|
478
|
+
if ((std::find(prod.begin(), prod.end(), grammar->strToKind("epsilon")) != prod.end()))
|
|
479
479
|
{
|
|
480
480
|
if (std::find(grammar->getEpsilonProds().begin(), grammar->getEpsilonProds().end(), prod) == grammar->getEpsilonProds().end())
|
|
481
481
|
{
|
|
@@ -484,13 +484,13 @@ void CFGNormalizer::insertToCFLGrammar(CFLGrammar *grammar, GrammarBase::Product
|
|
|
484
484
|
}
|
|
485
485
|
else
|
|
486
486
|
{
|
|
487
|
-
grammar->
|
|
487
|
+
grammar->getSingleRHSToProds()[prod[1]].insert(prod);
|
|
488
488
|
}
|
|
489
489
|
}
|
|
490
490
|
if (prod.size() == 3)
|
|
491
491
|
{
|
|
492
|
-
grammar->
|
|
493
|
-
grammar->
|
|
492
|
+
grammar->getFirstRHSToProds()[prod[1]].insert(prod);
|
|
493
|
+
grammar->getSecondRHSToProds()[prod[2]].insert(prod);
|
|
494
494
|
}
|
|
495
495
|
}
|
|
496
496
|
|