svf-tools 1.0.1021 → 1.0.1023
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/build.sh +4 -4
- package/package.json +1 -1
- package/svf/include/Graphs/CFLGraph.h +0 -1
- package/svf/lib/CFL/CFGNormalizer.cpp +15 -5
- package/svf/lib/CFL/CFLGraphBuilder.cpp +55 -26
- package/svf/lib/CFL/GrammarBuilder.cpp +72 -27
- package/svf-llvm/include/SVF-LLVM/ICFGBuilder.h +1 -1
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +4 -0
- package/svf-llvm/lib/ICFGBuilder.cpp +11 -12
- package/svf-llvm/lib/LLVMLoopAnalysis.cpp +1 -2
- package/svf-llvm/lib/LLVMModule.cpp +10 -2
- package/svf-llvm/lib/LLVMUtil.cpp +1 -2
package/build.sh
CHANGED
|
@@ -250,10 +250,10 @@ BUILD_DIR="./${BUILD_TYPE}-build"
|
|
|
250
250
|
rm -rf "${BUILD_DIR}"
|
|
251
251
|
mkdir "${BUILD_DIR}"
|
|
252
252
|
# If you need shared libs, turn BUILD_SHARED_LIBS on
|
|
253
|
-
cmake -D CMAKE_BUILD_TYPE:STRING="${BUILD_TYPE}"
|
|
254
|
-
-DSVF_ENABLE_ASSERTIONS:BOOL=true
|
|
255
|
-
-DSVF_SANITIZE="${SVF_SANITIZER}"
|
|
256
|
-
-DBUILD_SHARED_LIBS=off
|
|
253
|
+
cmake -D CMAKE_BUILD_TYPE:STRING="${BUILD_TYPE}" \
|
|
254
|
+
-DSVF_ENABLE_ASSERTIONS:BOOL=true \
|
|
255
|
+
-DSVF_SANITIZE="${SVF_SANITIZER}" \
|
|
256
|
+
-DBUILD_SHARED_LIBS=off \
|
|
257
257
|
-S "${SVFHOME}" -B "${BUILD_DIR}"
|
|
258
258
|
cmake --build "${BUILD_DIR}" -j ${jobs}
|
|
259
259
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1023",
|
|
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,7 +32,6 @@
|
|
|
32
32
|
#include "Util/WorkList.h"
|
|
33
33
|
#include "SVFIR/SVFValue.h"
|
|
34
34
|
#include <string>
|
|
35
|
-
#include <regex>
|
|
36
35
|
#include <fstream>
|
|
37
36
|
#include <sstream>
|
|
38
37
|
#include <iostream>
|
|
@@ -437,13 +436,23 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFGrammar *grammar)
|
|
|
437
436
|
|
|
438
437
|
void CFGNormalizer::strTrans(std::string LHS, CFGrammar *grammar, GrammarBase::Production& normalProd)
|
|
439
438
|
{
|
|
440
|
-
|
|
441
|
-
|
|
439
|
+
// Find the position of the first non-whitespace character
|
|
440
|
+
size_t start = LHS.find_first_not_of(" \t\n\r");
|
|
441
|
+
// If the string contains non-whitespace characters, remove leading spaces
|
|
442
|
+
if (start != std::string::npos)
|
|
443
|
+
{
|
|
444
|
+
LHS = LHS.substr(start);
|
|
445
|
+
}
|
|
446
|
+
else
|
|
447
|
+
{
|
|
448
|
+
// If the string contains only spaces, clear it
|
|
449
|
+
LHS.clear();
|
|
450
|
+
}
|
|
451
|
+
|
|
442
452
|
std::string delimiter;
|
|
443
453
|
size_t pos;
|
|
444
454
|
std::string word;
|
|
445
|
-
|
|
446
|
-
LHS = matches.str(1);
|
|
455
|
+
|
|
447
456
|
delimiter = " ";
|
|
448
457
|
while ((pos = LHS.find(delimiter)) != std::string::npos)
|
|
449
458
|
{
|
|
@@ -454,6 +463,7 @@ void CFGNormalizer::strTrans(std::string LHS, CFGrammar *grammar, GrammarBase::P
|
|
|
454
463
|
normalProd.push_back(grammar->strToSymbol(LHS));
|
|
455
464
|
}
|
|
456
465
|
|
|
466
|
+
|
|
457
467
|
GrammarBase::Symbol CFGNormalizer::check_head(GrammarBase::SymbolMap<GrammarBase::Symbol, GrammarBase::Productions> &grammar, GrammarBase::Production &rule)
|
|
458
468
|
{
|
|
459
469
|
for(auto symProdPair: grammar)
|
|
@@ -193,49 +193,79 @@ CFLGraph* CFLGraphBuilder::buildFromText(std::string fileName, GrammarBase *gram
|
|
|
193
193
|
return cflGraph;
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
CFLGraph *
|
|
196
|
+
CFLGraph *CFLGraphBuilder::buildFromDot(std::string fileName, GrammarBase *grammar, BuildDirection direction)
|
|
197
197
|
{
|
|
198
198
|
buildlabelToKindMap(grammar);
|
|
199
199
|
cflGraph = new CFLGraph(grammar->getStartKind());
|
|
200
200
|
std::string lineString;
|
|
201
201
|
std::ifstream inputFile(fileName);
|
|
202
202
|
std::cout << "Building CFL Graph from dot file: " << fileName << "..\n";
|
|
203
|
-
std::regex reg("Node(\\w+)\\s*->\\s*Node(\\w+)\\s*\\[.*label=(.*)\\]");
|
|
204
203
|
std::cout << std::boolalpha;
|
|
205
|
-
|
|
204
|
+
|
|
205
|
+
u32_t lineNum = 0;
|
|
206
206
|
current = labelToKindMap.size();
|
|
207
207
|
|
|
208
208
|
while (getline(inputFile, lineString))
|
|
209
209
|
{
|
|
210
210
|
lineNum += 1;
|
|
211
|
-
|
|
212
|
-
|
|
211
|
+
|
|
212
|
+
// Find "Node" prefixes and "->"
|
|
213
|
+
size_t srcStart = lineString.find("Node");
|
|
214
|
+
if (srcStart == std::string::npos) continue;
|
|
215
|
+
|
|
216
|
+
size_t srcEnd = lineString.find(" ", srcStart);
|
|
217
|
+
if (srcEnd == std::string::npos) continue;
|
|
218
|
+
|
|
219
|
+
size_t arrowPos = lineString.find("->", srcEnd);
|
|
220
|
+
if (arrowPos == std::string::npos) continue;
|
|
221
|
+
|
|
222
|
+
size_t dstStart = lineString.find("Node", arrowPos);
|
|
223
|
+
if (dstStart == std::string::npos) continue;
|
|
224
|
+
|
|
225
|
+
size_t dstEnd = lineString.find(" ", dstStart);
|
|
226
|
+
if (dstEnd == std::string::npos) continue;
|
|
227
|
+
|
|
228
|
+
size_t labelStart = lineString.find("label=", dstEnd);
|
|
229
|
+
if (labelStart == std::string::npos) continue;
|
|
230
|
+
|
|
231
|
+
labelStart += 6; // Move past "label=" to the start of the label
|
|
232
|
+
size_t labelEnd = lineString.find_first_of("]", labelStart);
|
|
233
|
+
if (labelEnd == std::string::npos) continue;
|
|
234
|
+
|
|
235
|
+
// Extract the source ID, destination ID, and label
|
|
236
|
+
std::string srcIDStr = lineString.substr(srcStart + 4, srcEnd - (srcStart + 4));
|
|
237
|
+
std::string dstIDStr = lineString.substr(dstStart + 4, dstEnd - (dstStart + 4));
|
|
238
|
+
std::string label = lineString.substr(labelStart, labelEnd - labelStart);
|
|
239
|
+
|
|
240
|
+
// Convert source and destination IDs from hexadecimal
|
|
241
|
+
u32_t srcID = std::stoul(srcIDStr, nullptr, 16);
|
|
242
|
+
u32_t dstID = std::stoul(dstIDStr, nullptr, 16);
|
|
243
|
+
|
|
244
|
+
CFLNode *src = addGNode(srcID);
|
|
245
|
+
CFLNode *dst = addGNode(dstID);
|
|
246
|
+
|
|
247
|
+
if (labelToKindMap.find(label) != labelToKindMap.end())
|
|
248
|
+
{
|
|
249
|
+
cflGraph->addCFLEdge(src, dst, labelToKindMap[label]);
|
|
250
|
+
}
|
|
251
|
+
else
|
|
213
252
|
{
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
CFLNode *src = addGNode(srcID);
|
|
218
|
-
CFLNode *dst = addGNode(dstID);
|
|
219
|
-
if (labelToKindMap.find(label) != labelToKindMap.end())
|
|
253
|
+
if (Options::FlexSymMap() == true)
|
|
254
|
+
{
|
|
255
|
+
labelToKindMap.insert({label, current++});
|
|
220
256
|
cflGraph->addCFLEdge(src, dst, labelToKindMap[label]);
|
|
257
|
+
}
|
|
221
258
|
else
|
|
222
259
|
{
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
else
|
|
229
|
-
{
|
|
230
|
-
std::string msg = "In line " + std::to_string(lineNum) +
|
|
231
|
-
" sym can not find in grammar, please correct the input dot or set --flexsymmap.";
|
|
232
|
-
SVFUtil::errMsg(msg);
|
|
233
|
-
std::cout << msg;
|
|
234
|
-
abort();
|
|
235
|
-
}
|
|
260
|
+
std::string msg = "In line " + std::to_string(lineNum) +
|
|
261
|
+
" sym cannot be found in grammar. Please correct the input dot or set --flexsymmap.";
|
|
262
|
+
SVFUtil::errMsg(msg);
|
|
263
|
+
std::cout << msg;
|
|
264
|
+
abort();
|
|
236
265
|
}
|
|
237
266
|
}
|
|
238
267
|
}
|
|
268
|
+
|
|
239
269
|
inputFile.close();
|
|
240
270
|
return cflGraph;
|
|
241
271
|
}
|
|
@@ -247,7 +277,6 @@ CFLGraph* CFLGraphBuilder::buildFromJson(std::string fileName, GrammarBase *gram
|
|
|
247
277
|
return cflGraph;
|
|
248
278
|
}
|
|
249
279
|
|
|
250
|
-
|
|
251
280
|
CFLGraph* AliasCFLGraphBuilder::buildBigraph(ConstraintGraph *graph, Kind startKind, GrammarBase *grammar)
|
|
252
281
|
{
|
|
253
282
|
cflGraph = new CFLGraph(startKind);
|
|
@@ -543,4 +572,4 @@ CFLGraph* VFCFLGraphBuilder::buildBiPEGgraph(ConstraintGraph *graph, Kind startK
|
|
|
543
572
|
}
|
|
544
573
|
|
|
545
574
|
|
|
546
|
-
} // end of SVF namespace
|
|
575
|
+
} // end of SVF namespace
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
|
|
30
30
|
#include <string>
|
|
31
31
|
#include <fstream>
|
|
32
|
-
#include <regex>
|
|
33
32
|
#include <sstream>
|
|
34
33
|
#include <iostream>
|
|
35
34
|
#include "CFL/GrammarBuilder.h"
|
|
@@ -44,48 +43,69 @@ const inline std::string GrammarBuilder::parseProductionsString() const
|
|
|
44
43
|
std::cerr << "Can't open CFL grammar file `" << fileName << "`" << std::endl;
|
|
45
44
|
abort();
|
|
46
45
|
}
|
|
46
|
+
|
|
47
47
|
std::string lineString;
|
|
48
48
|
std::string lines = "";
|
|
49
49
|
std::string startString;
|
|
50
50
|
std::string symbolString;
|
|
51
51
|
const std::string WHITESPACE = " \n\r\t\f\v";
|
|
52
52
|
int lineNum = 0;
|
|
53
|
+
|
|
53
54
|
while (getline(textFile, lineString))
|
|
54
55
|
{
|
|
55
|
-
if(lineNum == 1)
|
|
56
|
+
if (lineNum == 1)
|
|
56
57
|
{
|
|
57
58
|
startString = stripSpace(lineString);
|
|
58
59
|
}
|
|
59
|
-
if(lineNum == 3)
|
|
60
|
+
else if (lineNum == 3)
|
|
61
|
+
{
|
|
62
|
+
// Trim leading and trailing whitespace
|
|
63
|
+
size_t start = lineString.find_first_not_of(WHITESPACE);
|
|
64
|
+
size_t end = lineString.find_last_not_of(WHITESPACE);
|
|
65
|
+
if (start != std::string::npos && end != std::string::npos)
|
|
66
|
+
{
|
|
67
|
+
symbolString = lineString.substr(start, end - start + 1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Append line to `lines` with whitespace trimmed
|
|
72
|
+
size_t start = lineString.find_first_not_of(WHITESPACE);
|
|
73
|
+
size_t end = lineString.find_last_not_of(WHITESPACE);
|
|
74
|
+
if (start != std::string::npos && end != std::string::npos)
|
|
60
75
|
{
|
|
61
|
-
|
|
76
|
+
lines.append(lineString.substr(start, end - start + 1));
|
|
62
77
|
}
|
|
63
78
|
|
|
64
|
-
lines.append(lineString.substr(lineString.find_first_not_of(WHITESPACE), lineString.find_last_not_of(WHITESPACE)+1));
|
|
65
79
|
lineNum++;
|
|
66
80
|
}
|
|
67
81
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (std::
|
|
82
|
+
// Extract "Productions:" part from `lines` manually
|
|
83
|
+
size_t productionsPos = lines.find("Productions:");
|
|
84
|
+
if (productionsPos != std::string::npos)
|
|
71
85
|
{
|
|
72
|
-
lines =
|
|
86
|
+
lines = lines.substr(productionsPos + std::string("Productions:").length());
|
|
73
87
|
}
|
|
88
|
+
|
|
89
|
+
// Parse `symbolString` to insert symbols
|
|
74
90
|
std::string sString;
|
|
75
91
|
size_t pos = 0;
|
|
76
92
|
while ((pos = symbolString.find(" ")) != std::string::npos)
|
|
77
93
|
{
|
|
78
94
|
sString = stripSpace(symbolString.substr(0, pos));
|
|
79
|
-
symbolString.erase(0, pos + 1); //
|
|
95
|
+
symbolString.erase(0, pos + 1); // Remove the processed part
|
|
80
96
|
grammar->insertSymbol(sString);
|
|
81
97
|
}
|
|
98
|
+
// Insert the remaining symbol
|
|
82
99
|
grammar->insertSymbol(symbolString);
|
|
100
|
+
|
|
101
|
+
// Set the start kind and add the epsilon terminal
|
|
83
102
|
grammar->setStartKind(grammar->insertSymbol(startString));
|
|
84
103
|
grammar->insertTerminalKind("epsilon");
|
|
85
104
|
|
|
86
105
|
return lines;
|
|
87
106
|
}
|
|
88
107
|
|
|
108
|
+
|
|
89
109
|
const inline std::vector<std::string> GrammarBuilder::loadWordProductions() const
|
|
90
110
|
{
|
|
91
111
|
size_t pos = 0;
|
|
@@ -104,17 +124,21 @@ const inline std::vector<std::string> GrammarBuilder::loadWordProductions() cons
|
|
|
104
124
|
|
|
105
125
|
const inline std::string GrammarBuilder::stripSpace(std::string s) const
|
|
106
126
|
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
127
|
+
// Remove leading spaces
|
|
128
|
+
size_t start = s.find_first_not_of(" ");
|
|
129
|
+
if (start == std::string::npos)
|
|
130
|
+
{
|
|
131
|
+
return ""; // Return an empty string if no non-space character is found
|
|
132
|
+
}
|
|
112
133
|
|
|
134
|
+
// Remove trailing spaces
|
|
135
|
+
size_t end = s.find_last_not_of(" ");
|
|
136
|
+
return s.substr(start, end - start + 1);
|
|
137
|
+
}
|
|
113
138
|
|
|
114
|
-
///
|
|
139
|
+
/// Build grammarbase from textfile
|
|
115
140
|
GrammarBase* GrammarBuilder::build() const
|
|
116
141
|
{
|
|
117
|
-
std::smatch matches;
|
|
118
142
|
std::string delimiter = " ";
|
|
119
143
|
std::string delimiter1 = "->";
|
|
120
144
|
std::string word = "";
|
|
@@ -124,29 +148,50 @@ GrammarBase* GrammarBuilder::build() const
|
|
|
124
148
|
|
|
125
149
|
for (auto wordProd : wordProdVec)
|
|
126
150
|
{
|
|
151
|
+
// Find the position of the '->' delimiter
|
|
127
152
|
if ((pos = wordProd.find(delimiter1)) != std::string::npos)
|
|
128
153
|
{
|
|
154
|
+
// Extract and strip RHS (right-hand side) and LHS (left-hand side)
|
|
129
155
|
std::string RHS = stripSpace(wordProd.substr(0, pos));
|
|
130
|
-
std::string LHS = wordProd.substr(pos + delimiter1.size()
|
|
156
|
+
std::string LHS = stripSpace(wordProd.substr(pos + delimiter1.size()));
|
|
157
|
+
|
|
158
|
+
// Insert RHS symbol into grammar
|
|
131
159
|
GrammarBase::Symbol RHSSymbol = grammar->insertSymbol(RHS);
|
|
132
160
|
prod.push_back(RHSSymbol);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
161
|
+
|
|
162
|
+
// Ensure RHS symbol exists in raw productions
|
|
163
|
+
if (grammar->getRawProductions().find(RHSSymbol) == grammar->getRawProductions().end())
|
|
164
|
+
{
|
|
165
|
+
grammar->getRawProductions().insert({RHSSymbol, {}});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Parse LHS string into symbols
|
|
137
169
|
while ((pos = LHS.find(delimiter)) != std::string::npos)
|
|
138
170
|
{
|
|
139
|
-
word
|
|
140
|
-
LHS.
|
|
171
|
+
// Extract each word before the space
|
|
172
|
+
word = stripSpace(LHS.substr(0, pos));
|
|
173
|
+
LHS.erase(0, pos + delimiter.length());
|
|
174
|
+
|
|
175
|
+
// Insert symbol into production
|
|
141
176
|
prod.push_back(grammar->insertSymbol(word));
|
|
142
177
|
}
|
|
143
|
-
|
|
178
|
+
|
|
179
|
+
// Insert the remaining word (if any) into the production
|
|
180
|
+
if (!LHS.empty())
|
|
181
|
+
{
|
|
182
|
+
prod.push_back(grammar->insertSymbol(stripSpace(LHS)));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Add the production to raw productions
|
|
144
186
|
grammar->getRawProductions().at(RHSSymbol).insert(prod);
|
|
187
|
+
|
|
188
|
+
// Clear the production for the next iteration
|
|
145
189
|
prod = {};
|
|
146
190
|
}
|
|
147
191
|
}
|
|
148
192
|
|
|
149
193
|
return grammar;
|
|
150
|
-
};
|
|
151
|
-
|
|
152
194
|
}
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
}
|
|
@@ -75,7 +75,7 @@ private:
|
|
|
75
75
|
///@{
|
|
76
76
|
void processFunEntry(const Function* fun, WorkList& worklist);
|
|
77
77
|
|
|
78
|
-
void
|
|
78
|
+
void processUnreachableFromEntry(const Function* fun, WorkList& worklist);
|
|
79
79
|
|
|
80
80
|
void processFunBody(WorkList& worklist);
|
|
81
81
|
|
|
@@ -109,6 +109,8 @@ private:
|
|
|
109
109
|
FunToFunExitNodeMapTy FunToFunExitNodeMap; ///< map a function to its FunEntryICFGNode
|
|
110
110
|
CallGraph* callgraph;
|
|
111
111
|
|
|
112
|
+
Map<const Function*, DominatorTree> FunToDominatorTree;
|
|
113
|
+
|
|
112
114
|
/// Constructor
|
|
113
115
|
LLVMModuleSet();
|
|
114
116
|
|
|
@@ -397,6 +399,8 @@ public:
|
|
|
397
399
|
return icfg;
|
|
398
400
|
}
|
|
399
401
|
|
|
402
|
+
DominatorTree& getDomTree(const Function* fun);
|
|
403
|
+
|
|
400
404
|
private:
|
|
401
405
|
/// Create SVFTypes
|
|
402
406
|
SVFType* addSVFTypeInfo(const Type* t);
|
|
@@ -70,7 +70,7 @@ ICFG* ICFGBuilder::build()
|
|
|
70
70
|
continue;
|
|
71
71
|
WorkList worklist;
|
|
72
72
|
processFunEntry(fun,worklist);
|
|
73
|
-
|
|
73
|
+
processUnreachableFromEntry(fun, worklist);
|
|
74
74
|
processFunBody(worklist);
|
|
75
75
|
processFunExit(fun);
|
|
76
76
|
|
|
@@ -122,21 +122,20 @@ void ICFGBuilder::processFunEntry(const Function* fun, WorkList& worklist)
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
/*!
|
|
125
|
-
* bbs
|
|
125
|
+
* bbs unreachable from function entry
|
|
126
126
|
*/
|
|
127
|
-
void ICFGBuilder::
|
|
127
|
+
void ICFGBuilder::processUnreachableFromEntry(const Function* fun, WorkList& worklist)
|
|
128
128
|
{
|
|
129
|
-
|
|
129
|
+
SVFLoopAndDomInfo* pInfo =
|
|
130
|
+
llvmModuleSet()->getSVFFunction(fun)->getLoopAndDomInfo();
|
|
131
|
+
for (const auto& bb : *fun)
|
|
130
132
|
{
|
|
131
|
-
|
|
133
|
+
if (pInfo->isUnreachable(llvmModuleSet()->getSVFBasicBlock(&bb)) &&
|
|
134
|
+
!visited.count(&bb.front()))
|
|
132
135
|
{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
visited.insert(&inst);
|
|
137
|
-
(void)addBlockICFGNode(&inst);
|
|
138
|
-
worklist.push(&inst);
|
|
139
|
-
}
|
|
136
|
+
visited.insert(&bb.front());
|
|
137
|
+
(void)addBlockICFGNode(&bb.front());
|
|
138
|
+
worklist.push(&bb.front());
|
|
140
139
|
}
|
|
141
140
|
}
|
|
142
141
|
}
|
|
@@ -48,7 +48,6 @@ using namespace SVFUtil;
|
|
|
48
48
|
*/
|
|
49
49
|
void LLVMLoopAnalysis::buildLLVMLoops(SVFModule *mod, ICFG* icfg)
|
|
50
50
|
{
|
|
51
|
-
llvm::DominatorTree DT = llvm::DominatorTree();
|
|
52
51
|
std::vector<const Loop *> loop_stack;
|
|
53
52
|
for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
|
|
54
53
|
{
|
|
@@ -59,7 +58,7 @@ void LLVMLoopAnalysis::buildLLVMLoops(SVFModule *mod, ICFG* icfg)
|
|
|
59
58
|
if (func->isDeclaration()) continue;
|
|
60
59
|
// do not analyze external call
|
|
61
60
|
if (SVFUtil::isExtCall(svffun)) continue;
|
|
62
|
-
DT
|
|
61
|
+
llvm::DominatorTree& DT = LLVMModuleSet::getLLVMModuleSet()->getDomTree(func);
|
|
63
62
|
llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop> loopInfo;
|
|
64
63
|
std::vector<const Loop*> llvmLoops;
|
|
65
64
|
loopInfo.analyze(DT);
|
|
@@ -99,6 +99,15 @@ ObjTypeInference* LLVMModuleSet::getTypeInference()
|
|
|
99
99
|
return typeInference;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
DominatorTree& LLVMModuleSet::getDomTree(const SVF::Function* fun)
|
|
103
|
+
{
|
|
104
|
+
auto it = FunToDominatorTree.find(fun);
|
|
105
|
+
if(it != FunToDominatorTree.end()) return it->second;
|
|
106
|
+
DominatorTree& dt = FunToDominatorTree[fun];
|
|
107
|
+
dt.recalculate(const_cast<Function&>(*fun));
|
|
108
|
+
return dt;
|
|
109
|
+
}
|
|
110
|
+
|
|
102
111
|
SVFModule* LLVMModuleSet::buildSVFModule(Module &mod)
|
|
103
112
|
{
|
|
104
113
|
LLVMModuleSet* mset = getLLVMModuleSet();
|
|
@@ -407,9 +416,8 @@ void LLVMModuleSet::initDomTree(SVFFunction* svffun, const Function* fun)
|
|
|
407
416
|
if (fun->isDeclaration())
|
|
408
417
|
return;
|
|
409
418
|
//process and stored dt & df
|
|
410
|
-
DominatorTree dt;
|
|
411
419
|
DominanceFrontier df;
|
|
412
|
-
dt
|
|
420
|
+
DominatorTree& dt = getDomTree(fun);
|
|
413
421
|
df.analyze(dt);
|
|
414
422
|
LoopInfo loopInfo = LoopInfo(dt);
|
|
415
423
|
PostDominatorTree pdt = PostDominatorTree(const_cast<Function&>(*fun));
|
|
@@ -75,8 +75,7 @@ void LLVMUtil::getFunReachableBBs (const Function* fun, std::vector<const SVFBas
|
|
|
75
75
|
{
|
|
76
76
|
assert(!SVFUtil::isExtCall(LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun)) && "The calling function cannot be an external function.");
|
|
77
77
|
//initial DominatorTree
|
|
78
|
-
DominatorTree dt;
|
|
79
|
-
dt.recalculate(const_cast<Function&>(*fun));
|
|
78
|
+
DominatorTree& dt = LLVMModuleSet::getLLVMModuleSet()->getDomTree(fun);
|
|
80
79
|
|
|
81
80
|
Set<const BasicBlock*> visited;
|
|
82
81
|
std::vector<const BasicBlock*> bbVec;
|