svf-lib 1.0.1375 → 1.0.1376
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/SVF-osx/Release-build/svf-llvm/libSvfLLVM.a +0 -0
- package/SVF-osx/svf/include/include/AbstractExecution/AbstractValue.h +79 -0
- package/SVF-osx/svf/include/include/AbstractExecution/AddressValue.h +210 -0
- package/SVF-osx/svf/include/include/AbstractExecution/ExeState.h +223 -0
- package/SVF-osx/svf/include/include/AbstractExecution/IntervalExeState.h +425 -0
- package/SVF-osx/svf/include/include/AbstractExecution/IntervalValue.h +868 -0
- package/SVF-osx/svf/include/include/AbstractExecution/NumericLiteral.h +406 -0
- package/SVF-osx/svf/include/include/AbstractExecution/RelExeState.h +225 -0
- package/SVF-osx/svf/include/include/AbstractExecution/RelationSolver.h +68 -0
- package/SVF-osx/svf/include/include/AbstractExecution/SVFIR2ItvExeState.h +186 -0
- package/SVF-osx/svf/include/include/AbstractExecution/WTO.h +845 -0
- package/SVF-osx/svf/include/include/CFL/CFGNormalizer.h +84 -0
- package/SVF-osx/svf/include/include/CFL/CFLAlias.h +176 -0
- package/SVF-osx/svf/include/include/CFL/CFLBase.h +115 -0
- package/SVF-osx/svf/include/include/CFL/CFLData.h +316 -0
- package/SVF-osx/svf/include/include/CFL/CFLDataBuilder.h +91 -0
- package/SVF-osx/svf/include/include/CFL/CFLGramGraphChecker.h +74 -0
- package/SVF-osx/svf/include/include/CFL/CFLGrammar.h +468 -0
- package/SVF-osx/svf/include/include/CFL/CFLGrammar.txt +15 -0
- package/SVF-osx/svf/include/include/CFL/CFLGraphBuilder.h +193 -0
- package/SVF-osx/svf/include/include/CFL/CFLSolver.h +136 -0
- package/SVF-osx/svf/include/include/CFL/CFLStat.h +67 -0
- package/SVF-osx/svf/include/include/CFL/CFLVF.h +65 -0
- package/SVF-osx/svf/include/include/CFL/GrammarBuilder.h +100 -0
- package/SVF-osx/svf/include/include/CFL/PEGGrammar.txt +11 -0
- package/SVF-osx/svf/include/include/CFL/VFG.txt +7 -0
- package/SVF-osx/svf/include/include/DDA/ContextDDA.h +230 -0
- package/SVF-osx/svf/include/include/DDA/DDAClient.h +168 -0
- package/SVF-osx/svf/include/include/DDA/DDAPass.h +99 -0
- package/SVF-osx/svf/include/include/DDA/DDAStat.h +138 -0
- package/SVF-osx/svf/include/include/DDA/DDAVFSolver.h +789 -0
- package/SVF-osx/svf/include/include/DDA/FlowDDA.h +178 -0
- package/SVF-osx/svf/include/include/FastCluster/LICENSE.TXT +13 -0
- package/SVF-osx/svf/include/include/FastCluster/fastcluster.h +80 -0
- package/SVF-osx/svf/include/include/Graphs/CFLGraph.h +215 -0
- package/SVF-osx/svf/include/include/Graphs/CHG.h +351 -0
- package/SVF-osx/svf/include/include/Graphs/ConsG.h +408 -0
- package/SVF-osx/svf/include/include/Graphs/ConsGEdge.h +353 -0
- package/SVF-osx/svf/include/include/Graphs/ConsGNode.h +391 -0
- package/SVF-osx/svf/include/include/Graphs/DOTGraphTraits.h +188 -0
- package/SVF-osx/svf/include/include/Graphs/GenericGraph.h +620 -0
- package/SVF-osx/svf/include/include/Graphs/GraphPrinter.h +111 -0
- package/SVF-osx/svf/include/include/Graphs/GraphTraits.h +150 -0
- package/SVF-osx/svf/include/include/Graphs/GraphWriter.h +380 -0
- package/SVF-osx/svf/include/include/Graphs/ICFG.h +331 -0
- package/SVF-osx/svf/include/include/Graphs/ICFGEdge.h +264 -0
- package/SVF-osx/svf/include/include/Graphs/ICFGNode.h +523 -0
- package/SVF-osx/svf/include/include/Graphs/ICFGStat.h +164 -0
- package/SVF-osx/svf/include/include/Graphs/IRGraph.h +243 -0
- package/SVF-osx/svf/include/include/Graphs/PTACallGraph.h +471 -0
- package/SVF-osx/svf/include/include/Graphs/SVFG.h +490 -0
- package/SVF-osx/svf/include/include/Graphs/SVFGEdge.h +237 -0
- package/SVF-osx/svf/include/include/Graphs/SVFGNode.h +513 -0
- package/SVF-osx/svf/include/include/Graphs/SVFGOPT.h +362 -0
- package/SVF-osx/svf/include/include/Graphs/SVFGStat.h +273 -0
- package/SVF-osx/svf/include/include/Graphs/ThreadCallGraph.h +422 -0
- package/SVF-osx/svf/include/include/Graphs/VFG.h +664 -0
- package/SVF-osx/svf/include/include/Graphs/VFGEdge.h +295 -0
- package/SVF-osx/svf/include/include/Graphs/VFGNode.h +1197 -0
- package/SVF-osx/svf/include/include/MSSA/MSSAMuChi.h +722 -0
- package/SVF-osx/svf/include/include/MSSA/MemPartition.h +169 -0
- package/SVF-osx/svf/include/include/MSSA/MemRegion.h +491 -0
- package/SVF-osx/svf/include/include/MSSA/MemSSA.h +452 -0
- package/SVF-osx/svf/include/include/MSSA/SVFGBuilder.h +98 -0
- package/SVF-osx/svf/include/include/MTA/FSMPTA.h +270 -0
- package/SVF-osx/svf/include/include/MTA/LockAnalysis.h +517 -0
- package/SVF-osx/svf/include/include/MTA/MHP.h +565 -0
- package/SVF-osx/svf/include/include/MTA/MTA.h +101 -0
- package/SVF-osx/svf/include/include/MTA/MTAResultValidator.h +448 -0
- package/SVF-osx/svf/include/include/MTA/MTAStat.h +74 -0
- package/SVF-osx/svf/include/include/MTA/PCG.h +229 -0
- package/SVF-osx/svf/include/include/MTA/TCT.h +599 -0
- package/SVF-osx/svf/include/include/MemoryModel/AbstractPointsToDS.h +316 -0
- package/SVF-osx/svf/include/include/MemoryModel/ConditionalPT.h +878 -0
- package/SVF-osx/svf/include/include/MemoryModel/LocationSet.h +148 -0
- package/SVF-osx/svf/include/include/MemoryModel/MutablePointsToDS.h +1025 -0
- package/SVF-osx/svf/include/include/MemoryModel/PersistentPointsToCache.h +463 -0
- package/SVF-osx/svf/include/include/MemoryModel/PersistentPointsToDS.h +955 -0
- package/SVF-osx/svf/include/include/MemoryModel/PointerAnalysis.h +452 -0
- package/SVF-osx/svf/include/include/MemoryModel/PointerAnalysisImpl.h +590 -0
- package/SVF-osx/svf/include/include/MemoryModel/PointsTo.h +255 -0
- package/SVF-osx/svf/include/include/MemoryModel/SVFLoop.h +164 -0
- package/SVF-osx/svf/include/include/SABER/DoubleFreeChecker.h +76 -0
- package/SVF-osx/svf/include/include/SABER/FileChecker.h +82 -0
- package/SVF-osx/svf/include/include/SABER/LeakChecker.h +124 -0
- package/SVF-osx/svf/include/include/SABER/ProgSlice.h +313 -0
- package/SVF-osx/svf/include/include/SABER/SaberCheckerAPI.h +166 -0
- package/SVF-osx/svf/include/include/SABER/SaberCondAllocator.h +310 -0
- package/SVF-osx/svf/include/include/SABER/SaberSVFGBuilder.h +104 -0
- package/SVF-osx/svf/include/include/SABER/SrcSnkDDA.h +321 -0
- package/SVF-osx/svf/include/include/SABER/SrcSnkSolver.h +186 -0
- package/SVF-osx/svf/include/include/SVFIR/PAGBuilderFromFile.h +80 -0
- package/SVF-osx/svf/include/include/SVFIR/SVFIR.h +659 -0
- package/SVF-osx/svf/include/include/SVFIR/SVFModule.h +233 -0
- package/SVF-osx/svf/include/include/SVFIR/SVFStatements.h +1136 -0
- package/SVF-osx/svf/include/include/SVFIR/SVFType.h +527 -0
- package/SVF-osx/svf/include/include/SVFIR/SVFValue.h +1120 -0
- package/SVF-osx/svf/include/include/SVFIR/SVFVariables.h +721 -0
- package/SVF-osx/svf/include/include/SVFIR/SymbolTableInfo.h +597 -0
- package/SVF-osx/svf/include/include/Util/Annotator.h +180 -0
- package/SVF-osx/svf/include/include/Util/BitVector.h +55 -0
- package/SVF-osx/svf/include/include/Util/CallGraphBuilder.h +74 -0
- package/SVF-osx/svf/include/include/Util/Casting.h +426 -0
- package/SVF-osx/svf/include/include/Util/CommandLine.h +530 -0
- package/SVF-osx/svf/include/include/Util/CoreBitVector.h +214 -0
- package/SVF-osx/svf/include/include/Util/CppUtil.h +81 -0
- package/SVF-osx/svf/include/include/Util/CxtStmt.h +501 -0
- package/SVF-osx/svf/include/include/Util/DPItem.h +618 -0
- package/SVF-osx/svf/include/include/Util/ExtAPI.h +339 -0
- package/SVF-osx/svf/include/include/Util/ExtAPI.json +5707 -0
- package/SVF-osx/svf/include/include/Util/GraphReachSolver.h +186 -0
- package/SVF-osx/svf/include/include/Util/NodeIDAllocator.h +194 -0
- package/SVF-osx/svf/include/include/Util/Options.h +266 -0
- package/SVF-osx/svf/include/include/Util/PTAStat.h +65 -0
- package/SVF-osx/svf/include/include/Util/SCC.h +354 -0
- package/SVF-osx/svf/include/include/Util/SVFStat.h +100 -0
- package/SVF-osx/svf/include/include/Util/SVFUtil.h +660 -0
- package/SVF-osx/svf/include/include/Util/SparseBitVector.h +1202 -0
- package/SVF-osx/svf/include/include/Util/ThreadAPI.h +330 -0
- package/SVF-osx/svf/include/include/Util/WorkList.h +317 -0
- package/SVF-osx/svf/include/include/Util/Z3Expr.h +318 -0
- package/SVF-osx/svf/include/include/Util/cJSON.h +300 -0
- package/SVF-osx/svf/include/include/Util/iterator.h +407 -0
- package/SVF-osx/svf/include/include/Util/iterator_range.h +76 -0
- package/SVF-osx/svf/include/include/WPA/Andersen.h +416 -0
- package/SVF-osx/svf/include/include/WPA/AndersenPWC.h +160 -0
- package/SVF-osx/svf/include/include/WPA/CSC.h +95 -0
- package/SVF-osx/svf/include/include/WPA/FlowSensitive.h +317 -0
- package/SVF-osx/svf/include/include/WPA/Steensgaard.h +126 -0
- package/SVF-osx/svf/include/include/WPA/TypeAnalysis.h +83 -0
- package/SVF-osx/svf/include/include/WPA/VersionedFlowSensitive.h +287 -0
- package/SVF-osx/svf/include/include/WPA/WPAFSSolver.h +254 -0
- package/SVF-osx/svf/include/include/WPA/WPAPass.h +119 -0
- package/SVF-osx/svf/include/include/WPA/WPASolver.h +205 -0
- package/SVF-osx/svf/include/include/WPA/WPAStat.h +222 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/BasicTypes.h +250 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/BreakConstantExpr.h +94 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/CHGBuilder.h +73 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/DCHG.h +484 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/GEPTypeBridgeIterator.h +183 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/ICFGBuilder.h +106 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/LLVMLoopAnalysis.h +61 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/LLVMModule.h +360 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/LLVMUtil.h +466 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/SVFIRBuilder.h +417 -0
- package/SVF-osx/svf-llvm/include/SVF-LLVM/SVF-LLVM/SymbolTableBuilder.h +110 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1136 @@
|
|
|
1
|
+
//===- SVFStatements.h -- SVF statements-------------------------------------------//
|
|
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
|
+
/*
|
|
25
|
+
* SVFStatements.h
|
|
26
|
+
*
|
|
27
|
+
* Created on: Nov 10, 2013
|
|
28
|
+
* Author: Yulei Sui
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
#ifndef INCLUDE_SVFIR_SVFSTATEMENT_H_
|
|
32
|
+
#define INCLUDE_SVFIR_SVFSTATEMENT_H_
|
|
33
|
+
|
|
34
|
+
#include "Graphs/GenericGraph.h"
|
|
35
|
+
#include "MemoryModel/LocationSet.h"
|
|
36
|
+
|
|
37
|
+
namespace SVF
|
|
38
|
+
{
|
|
39
|
+
|
|
40
|
+
class SVFVar;
|
|
41
|
+
class ICFGNode;
|
|
42
|
+
class IntraICFGNode;
|
|
43
|
+
class CallICFGNode;
|
|
44
|
+
class FunEntryICFGNode;
|
|
45
|
+
class FunExitICFGNode;
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
* SVFIR program statements (PAGEdges)
|
|
49
|
+
*/
|
|
50
|
+
typedef GenericEdge<SVFVar> GenericPAGEdgeTy;
|
|
51
|
+
class SVFStmt : public GenericPAGEdgeTy
|
|
52
|
+
{
|
|
53
|
+
|
|
54
|
+
public:
|
|
55
|
+
/// Types of SVFIR statements
|
|
56
|
+
/// Gep represents (base + offset) for field sensitivity
|
|
57
|
+
/// ThreadFork/ThreadJoin is to model parameter passings between thread spawners and spawnees.
|
|
58
|
+
enum PEDGEK
|
|
59
|
+
{
|
|
60
|
+
Addr, Copy, Store, Load, Call, Ret, Gep, Phi, Select, Cmp, BinaryOp, UnaryOp, Branch, ThreadFork, ThreadJoin
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
private:
|
|
64
|
+
const SVFValue* value; ///< LLVM value
|
|
65
|
+
const SVFBasicBlock* basicBlock; ///< LLVM BasicBlock
|
|
66
|
+
ICFGNode *icfgNode; ///< ICFGNode
|
|
67
|
+
EdgeID edgeId; ///< Edge ID
|
|
68
|
+
public:
|
|
69
|
+
static u32_t totalEdgeNum; ///< Total edge number
|
|
70
|
+
|
|
71
|
+
/// Constructor
|
|
72
|
+
SVFStmt(SVFVar* s, SVFVar* d, GEdgeFlag k, bool real=true);
|
|
73
|
+
/// Destructor
|
|
74
|
+
~SVFStmt()
|
|
75
|
+
{
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/// ClassOf
|
|
79
|
+
//@{
|
|
80
|
+
static inline bool classof(const SVFStmt*)
|
|
81
|
+
{
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
85
|
+
{
|
|
86
|
+
return edge->getEdgeKind() == SVFStmt::Addr ||
|
|
87
|
+
edge->getEdgeKind() == SVFStmt::Copy ||
|
|
88
|
+
edge->getEdgeKind() == SVFStmt::Store ||
|
|
89
|
+
edge->getEdgeKind() == SVFStmt::Load ||
|
|
90
|
+
edge->getEdgeKind() == SVFStmt::Call ||
|
|
91
|
+
edge->getEdgeKind() == SVFStmt::Ret ||
|
|
92
|
+
edge->getEdgeKind() == SVFStmt::Gep ||
|
|
93
|
+
edge->getEdgeKind() == SVFStmt::Cmp ||
|
|
94
|
+
edge->getEdgeKind() == SVFStmt::BinaryOp ||
|
|
95
|
+
edge->getEdgeKind() == SVFStmt::UnaryOp ||
|
|
96
|
+
edge->getEdgeKind() == SVFStmt::ThreadFork ||
|
|
97
|
+
edge->getEdgeKind() == SVFStmt::ThreadJoin;
|
|
98
|
+
}
|
|
99
|
+
///@}
|
|
100
|
+
|
|
101
|
+
/// Return Edge ID
|
|
102
|
+
inline EdgeID getEdgeID() const
|
|
103
|
+
{
|
|
104
|
+
return edgeId;
|
|
105
|
+
}
|
|
106
|
+
/// Whether src and dst nodes are both of pointer type
|
|
107
|
+
bool isPTAEdge() const;
|
|
108
|
+
|
|
109
|
+
/// Get/set methods for llvm instruction
|
|
110
|
+
//@{
|
|
111
|
+
inline const SVFInstruction* getInst() const
|
|
112
|
+
{
|
|
113
|
+
if (const SVFInstruction* i = SVFUtil::dyn_cast<SVFInstruction>(value))
|
|
114
|
+
return i;
|
|
115
|
+
return nullptr;
|
|
116
|
+
}
|
|
117
|
+
inline void setValue(const SVFValue* val)
|
|
118
|
+
{
|
|
119
|
+
value = val;
|
|
120
|
+
}
|
|
121
|
+
inline const SVFValue* getValue() const
|
|
122
|
+
{
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
inline void setBB(const SVFBasicBlock* bb)
|
|
126
|
+
{
|
|
127
|
+
basicBlock = bb;
|
|
128
|
+
}
|
|
129
|
+
inline const SVFBasicBlock* getBB() const
|
|
130
|
+
{
|
|
131
|
+
return basicBlock;
|
|
132
|
+
}
|
|
133
|
+
inline void setICFGNode(ICFGNode *node)
|
|
134
|
+
{
|
|
135
|
+
icfgNode = node;
|
|
136
|
+
}
|
|
137
|
+
inline ICFGNode* getICFGNode() const
|
|
138
|
+
{
|
|
139
|
+
return icfgNode;
|
|
140
|
+
}
|
|
141
|
+
//@}
|
|
142
|
+
|
|
143
|
+
/// Compute the unique edgeFlag value from edge kind and second variable operand for MultiOpndStmt.
|
|
144
|
+
static inline GEdgeFlag makeEdgeFlagWithAddionalOpnd(GEdgeKind k, const SVFVar* var)
|
|
145
|
+
{
|
|
146
|
+
Var2LabelMap::const_iterator iter = var2LabelMap.find(var);
|
|
147
|
+
u64_t label = (iter != var2LabelMap.end()) ?
|
|
148
|
+
iter->second : multiOpndLabelCounter++;
|
|
149
|
+
return (label << EdgeKindMaskBits) | k;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/// Compute the unique edgeFlag value from edge kind and call site Instruction.
|
|
153
|
+
static inline GEdgeFlag makeEdgeFlagWithCallInst(GEdgeKind k, const ICFGNode* cs)
|
|
154
|
+
{
|
|
155
|
+
Inst2LabelMap::const_iterator iter = inst2LabelMap.find(cs);
|
|
156
|
+
u64_t label = (iter != inst2LabelMap.end()) ?
|
|
157
|
+
iter->second : callEdgeLabelCounter++;
|
|
158
|
+
return (label << EdgeKindMaskBits) | k;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/// Compute the unique edgeFlag value from edge kind and store Instruction.
|
|
162
|
+
/// Two store instructions may share the same StorePAGEdge
|
|
163
|
+
static inline GEdgeFlag makeEdgeFlagWithStoreInst(GEdgeKind k, const ICFGNode* store)
|
|
164
|
+
{
|
|
165
|
+
Inst2LabelMap::const_iterator iter = inst2LabelMap.find(store);
|
|
166
|
+
u64_t label = (iter != inst2LabelMap.end()) ?
|
|
167
|
+
iter->second : storeEdgeLabelCounter++;
|
|
168
|
+
return (label << EdgeKindMaskBits) | k;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
virtual const std::string toString() const;
|
|
172
|
+
|
|
173
|
+
//@}
|
|
174
|
+
/// Overloading operator << for dumping SVFVar value
|
|
175
|
+
//@{
|
|
176
|
+
friend OutStream& operator<<(OutStream& o, const SVFStmt& edge)
|
|
177
|
+
{
|
|
178
|
+
o << edge.toString();
|
|
179
|
+
return o;
|
|
180
|
+
}
|
|
181
|
+
//@}
|
|
182
|
+
|
|
183
|
+
typedef GenericNode<SVFVar,SVFStmt>::GEdgeSetTy SVFStmtSetTy;
|
|
184
|
+
typedef Map<EdgeID, SVFStmtSetTy> PAGEdgeToSetMapTy;
|
|
185
|
+
typedef PAGEdgeToSetMapTy KindToSVFStmtMapTy;
|
|
186
|
+
typedef SVFStmtSetTy PAGEdgeSetTy;
|
|
187
|
+
|
|
188
|
+
private:
|
|
189
|
+
typedef Map<const ICFGNode*, u32_t> Inst2LabelMap;
|
|
190
|
+
typedef Map<const SVFVar*, u32_t> Var2LabelMap;
|
|
191
|
+
static Inst2LabelMap inst2LabelMap; ///< Call site Instruction to label map
|
|
192
|
+
static Var2LabelMap var2LabelMap; ///< Second operand of MultiOpndStmt to label map
|
|
193
|
+
static u64_t callEdgeLabelCounter; ///< Call site Instruction counter
|
|
194
|
+
static u64_t storeEdgeLabelCounter; ///< Store Instruction counter
|
|
195
|
+
static u64_t multiOpndLabelCounter; ///< MultiOpndStmt counter
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/*
|
|
199
|
+
Parent class of Addr, Copy, Store, Load, Call, Ret, NormalGep, VariantGep, ThreadFork, ThreadJoin
|
|
200
|
+
connecting RHS expression and LHS expression with an assignment (e.g., LHSExpr = RHSExpr)
|
|
201
|
+
Only one operand on the right handside of an assignment
|
|
202
|
+
*/
|
|
203
|
+
class AssignStmt : public SVFStmt
|
|
204
|
+
{
|
|
205
|
+
|
|
206
|
+
private:
|
|
207
|
+
AssignStmt(); ///< place holder
|
|
208
|
+
AssignStmt(const AssignStmt &); ///< place holder
|
|
209
|
+
void operator=(const AssignStmt &); ///< place holder
|
|
210
|
+
SVFVar* getSrcNode(); ///< not allowed, use getRHSVar() instead
|
|
211
|
+
SVFVar* getDstNode(); ///< not allowed, use getLHSVar() instead
|
|
212
|
+
NodeID getSrcID(); ///< not allowed, use getRHSVarID() instead
|
|
213
|
+
NodeID getDstID(); ///< not allowed, use getLHSVarID() instead
|
|
214
|
+
|
|
215
|
+
protected:
|
|
216
|
+
/// constructor
|
|
217
|
+
AssignStmt(SVFVar* s, SVFVar* d, GEdgeFlag k) : SVFStmt(s,d,k)
|
|
218
|
+
{
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public:
|
|
222
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
223
|
+
//@{
|
|
224
|
+
static inline bool classof(const AssignStmt *)
|
|
225
|
+
{
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
static inline bool classof(const SVFStmt *edge)
|
|
229
|
+
{
|
|
230
|
+
return edge->getEdgeKind() == SVFStmt::Addr ||
|
|
231
|
+
edge->getEdgeKind() == SVFStmt::Copy ||
|
|
232
|
+
edge->getEdgeKind() == SVFStmt::Store ||
|
|
233
|
+
edge->getEdgeKind() == SVFStmt::Load ||
|
|
234
|
+
edge->getEdgeKind() == SVFStmt::Call ||
|
|
235
|
+
edge->getEdgeKind() == SVFStmt::Ret ||
|
|
236
|
+
edge->getEdgeKind() == SVFStmt::Gep ||
|
|
237
|
+
edge->getEdgeKind() == SVFStmt::ThreadFork ||
|
|
238
|
+
edge->getEdgeKind() == SVFStmt::ThreadJoin;
|
|
239
|
+
}
|
|
240
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
241
|
+
{
|
|
242
|
+
return edge->getEdgeKind() == SVFStmt::Addr ||
|
|
243
|
+
edge->getEdgeKind() == SVFStmt::Copy ||
|
|
244
|
+
edge->getEdgeKind() == SVFStmt::Store ||
|
|
245
|
+
edge->getEdgeKind() == SVFStmt::Load ||
|
|
246
|
+
edge->getEdgeKind() == SVFStmt::Call ||
|
|
247
|
+
edge->getEdgeKind() == SVFStmt::Ret ||
|
|
248
|
+
edge->getEdgeKind() == SVFStmt::Gep ||
|
|
249
|
+
edge->getEdgeKind() == SVFStmt::ThreadFork ||
|
|
250
|
+
edge->getEdgeKind() == SVFStmt::ThreadJoin;
|
|
251
|
+
}
|
|
252
|
+
//@}
|
|
253
|
+
|
|
254
|
+
inline SVFVar* getRHSVar() const
|
|
255
|
+
{
|
|
256
|
+
return SVFStmt::getSrcNode();
|
|
257
|
+
}
|
|
258
|
+
inline SVFVar* getLHSVar() const
|
|
259
|
+
{
|
|
260
|
+
return SVFStmt::getDstNode();
|
|
261
|
+
}
|
|
262
|
+
inline NodeID getRHSVarID() const
|
|
263
|
+
{
|
|
264
|
+
return SVFStmt::getSrcID();
|
|
265
|
+
}
|
|
266
|
+
inline NodeID getLHSVarID() const
|
|
267
|
+
{
|
|
268
|
+
return SVFStmt::getDstID();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
virtual const std::string toString() const = 0;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/*!
|
|
275
|
+
* Address statement (memory allocations)
|
|
276
|
+
*/
|
|
277
|
+
class AddrStmt: public AssignStmt
|
|
278
|
+
{
|
|
279
|
+
private:
|
|
280
|
+
AddrStmt(); ///< place holder
|
|
281
|
+
AddrStmt(const AddrStmt &); ///< place holder
|
|
282
|
+
void operator=(const AddrStmt &); ///< place holder
|
|
283
|
+
|
|
284
|
+
public:
|
|
285
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
286
|
+
//@{
|
|
287
|
+
static inline bool classof(const AddrStmt *)
|
|
288
|
+
{
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
static inline bool classof(const SVFStmt *edge)
|
|
292
|
+
{
|
|
293
|
+
return edge->getEdgeKind() == SVFStmt::Addr;
|
|
294
|
+
}
|
|
295
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
296
|
+
{
|
|
297
|
+
return edge->getEdgeKind() == SVFStmt::Addr;
|
|
298
|
+
}
|
|
299
|
+
//@}
|
|
300
|
+
|
|
301
|
+
/// constructor
|
|
302
|
+
AddrStmt(SVFVar* s, SVFVar* d) : AssignStmt(s,d,SVFStmt::Addr)
|
|
303
|
+
{
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
virtual const std::string toString() const override;
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
/*!
|
|
311
|
+
* Copy statements (simple assignment and casting)
|
|
312
|
+
*/
|
|
313
|
+
class CopyStmt: public AssignStmt
|
|
314
|
+
{
|
|
315
|
+
private:
|
|
316
|
+
CopyStmt(); ///< place holder
|
|
317
|
+
CopyStmt(const CopyStmt &); ///< place holder
|
|
318
|
+
void operator=(const CopyStmt &); ///< place holder
|
|
319
|
+
public:
|
|
320
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
321
|
+
//@{
|
|
322
|
+
static inline bool classof(const CopyStmt *)
|
|
323
|
+
{
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
static inline bool classof(const SVFStmt *edge)
|
|
327
|
+
{
|
|
328
|
+
return edge->getEdgeKind() == SVFStmt::Copy;
|
|
329
|
+
}
|
|
330
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
331
|
+
{
|
|
332
|
+
return edge->getEdgeKind() == SVFStmt::Copy;
|
|
333
|
+
}
|
|
334
|
+
//@}
|
|
335
|
+
|
|
336
|
+
/// constructor
|
|
337
|
+
CopyStmt(SVFVar* s, SVFVar* d) : AssignStmt(s,d,SVFStmt::Copy)
|
|
338
|
+
{
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
virtual const std::string toString() const override;
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
/*!
|
|
345
|
+
* Store statement
|
|
346
|
+
*/
|
|
347
|
+
class StoreStmt: public AssignStmt
|
|
348
|
+
{
|
|
349
|
+
private:
|
|
350
|
+
StoreStmt(); ///< place holder
|
|
351
|
+
StoreStmt(const StoreStmt &); ///< place holder
|
|
352
|
+
void operator=(const StoreStmt &); ///< place holder
|
|
353
|
+
|
|
354
|
+
public:
|
|
355
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
356
|
+
//@{
|
|
357
|
+
static inline bool classof(const StoreStmt *)
|
|
358
|
+
{
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
static inline bool classof(const SVFStmt *edge)
|
|
362
|
+
{
|
|
363
|
+
return edge->getEdgeKind() == SVFStmt::Store;
|
|
364
|
+
}
|
|
365
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
366
|
+
{
|
|
367
|
+
return edge->getEdgeKind() == SVFStmt::Store;
|
|
368
|
+
}
|
|
369
|
+
//@}
|
|
370
|
+
|
|
371
|
+
/// constructor
|
|
372
|
+
StoreStmt(SVFVar* s, SVFVar* d, const IntraICFGNode* st);
|
|
373
|
+
|
|
374
|
+
virtual const std::string toString() const override;
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
/*!
|
|
379
|
+
* Load statement
|
|
380
|
+
*/
|
|
381
|
+
class LoadStmt: public AssignStmt
|
|
382
|
+
{
|
|
383
|
+
private:
|
|
384
|
+
LoadStmt(); ///< place holder
|
|
385
|
+
LoadStmt(const LoadStmt &); ///< place holder
|
|
386
|
+
void operator=(const LoadStmt &); ///< place holder
|
|
387
|
+
|
|
388
|
+
public:
|
|
389
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
390
|
+
//@{
|
|
391
|
+
static inline bool classof(const LoadStmt *)
|
|
392
|
+
{
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
static inline bool classof(const SVFStmt *edge)
|
|
396
|
+
{
|
|
397
|
+
return edge->getEdgeKind() == SVFStmt::Load;
|
|
398
|
+
}
|
|
399
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
400
|
+
{
|
|
401
|
+
return edge->getEdgeKind() == SVFStmt::Load;
|
|
402
|
+
}
|
|
403
|
+
//@}
|
|
404
|
+
|
|
405
|
+
/// constructor
|
|
406
|
+
LoadStmt(SVFVar* s, SVFVar* d) : AssignStmt(s,d,SVFStmt::Load)
|
|
407
|
+
{
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
virtual const std::string toString() const override;
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
/*!
|
|
415
|
+
* Gep statement for struct field access, array access and pointer arithmetic
|
|
416
|
+
*/
|
|
417
|
+
class GepStmt: public AssignStmt
|
|
418
|
+
{
|
|
419
|
+
private:
|
|
420
|
+
GepStmt(); ///< place holder
|
|
421
|
+
GepStmt(const GepStmt &); ///< place holder
|
|
422
|
+
void operator=(const GepStmt &); ///< place holder
|
|
423
|
+
|
|
424
|
+
LocationSet ls; ///< location set of the gep edge
|
|
425
|
+
bool variantField; ///< Gep statement with a variant field index (pointer arithmetic) for struct field access (e.g., p = &(q + f), where f is a variable)
|
|
426
|
+
public:
|
|
427
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
428
|
+
//@{
|
|
429
|
+
static inline bool classof(const GepStmt *)
|
|
430
|
+
{
|
|
431
|
+
return true;
|
|
432
|
+
}
|
|
433
|
+
static inline bool classof(const SVFStmt *edge)
|
|
434
|
+
{
|
|
435
|
+
return edge->getEdgeKind() == SVFStmt::Gep;
|
|
436
|
+
}
|
|
437
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
438
|
+
{
|
|
439
|
+
return edge->getEdgeKind() == SVFStmt::Gep;
|
|
440
|
+
}
|
|
441
|
+
//@}
|
|
442
|
+
|
|
443
|
+
inline const LocationSet& getLocationSet() const
|
|
444
|
+
{
|
|
445
|
+
return ls;
|
|
446
|
+
}
|
|
447
|
+
inline const LocationSet::OffsetValueVec& getOffsetValueVec() const
|
|
448
|
+
{
|
|
449
|
+
return getLocationSet().getOffsetValueVec();
|
|
450
|
+
}
|
|
451
|
+
/// Return TRUE if this is a constant location set.
|
|
452
|
+
inline bool isConstantOffset() const
|
|
453
|
+
{
|
|
454
|
+
return getLocationSet().isConstantOffset();
|
|
455
|
+
}
|
|
456
|
+
/// Return accumulated constant offset (when accessing array or struct) if this offset is a constant.
|
|
457
|
+
inline s32_t accumulateConstantOffset() const
|
|
458
|
+
{
|
|
459
|
+
return getLocationSet().accumulateConstantOffset();
|
|
460
|
+
}
|
|
461
|
+
/// Field index of the gep statement if it access the field of a struct
|
|
462
|
+
inline s32_t getConstantFieldIdx() const
|
|
463
|
+
{
|
|
464
|
+
assert(isVariantFieldGep()==false && "Can't retrieve the LocationSet if using a variable field index (pointer arithmetic) for struct field access ");
|
|
465
|
+
return getLocationSet().accumulateConstantFieldIdx();
|
|
466
|
+
}
|
|
467
|
+
/// Gep statement with a variant field index (pointer arithmetic) for struct field access
|
|
468
|
+
inline bool isVariantFieldGep() const
|
|
469
|
+
{
|
|
470
|
+
return variantField;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/// constructor
|
|
474
|
+
GepStmt(SVFVar* s, SVFVar* d, const LocationSet& l, bool varfld=false) : AssignStmt(s,d,SVFStmt::Gep), ls(l), variantField(varfld)
|
|
475
|
+
{
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
virtual const std::string toString() const;
|
|
479
|
+
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
/*!
|
|
484
|
+
* Call
|
|
485
|
+
*/
|
|
486
|
+
class CallPE: public AssignStmt
|
|
487
|
+
{
|
|
488
|
+
private:
|
|
489
|
+
CallPE(); ///< place holder
|
|
490
|
+
CallPE(const CallPE &); ///< place holder
|
|
491
|
+
void operator=(const CallPE &); ///< place holder
|
|
492
|
+
|
|
493
|
+
const CallICFGNode* call; /// the callsite statement calling from
|
|
494
|
+
const FunEntryICFGNode* entry; /// the function exit statement calling to
|
|
495
|
+
public:
|
|
496
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
497
|
+
//@{
|
|
498
|
+
static inline bool classof(const CallPE *)
|
|
499
|
+
{
|
|
500
|
+
return true;
|
|
501
|
+
}
|
|
502
|
+
static inline bool classof(const SVFStmt *edge)
|
|
503
|
+
{
|
|
504
|
+
return edge->getEdgeKind() == SVFStmt::Call
|
|
505
|
+
|| edge->getEdgeKind() == SVFStmt::ThreadFork;
|
|
506
|
+
}
|
|
507
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
508
|
+
{
|
|
509
|
+
return edge->getEdgeKind() == SVFStmt::Call
|
|
510
|
+
|| edge->getEdgeKind() == SVFStmt::ThreadFork;
|
|
511
|
+
}
|
|
512
|
+
//@}
|
|
513
|
+
|
|
514
|
+
/// constructor
|
|
515
|
+
CallPE(SVFVar* s, SVFVar* d, const CallICFGNode* i,
|
|
516
|
+
const FunEntryICFGNode* e, GEdgeKind k = SVFStmt::Call);
|
|
517
|
+
|
|
518
|
+
/// Get method for the call instruction
|
|
519
|
+
//@{
|
|
520
|
+
inline const CallICFGNode* getCallInst() const
|
|
521
|
+
{
|
|
522
|
+
return call;
|
|
523
|
+
}
|
|
524
|
+
inline const CallICFGNode* getCallSite() const
|
|
525
|
+
{
|
|
526
|
+
return call;
|
|
527
|
+
}
|
|
528
|
+
inline const FunEntryICFGNode* getFunEntryICFGNode() const
|
|
529
|
+
{
|
|
530
|
+
return entry;
|
|
531
|
+
}
|
|
532
|
+
//@}
|
|
533
|
+
|
|
534
|
+
virtual const std::string toString() const override;
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
/*!
|
|
539
|
+
* Return
|
|
540
|
+
*/
|
|
541
|
+
class RetPE: public AssignStmt
|
|
542
|
+
{
|
|
543
|
+
private:
|
|
544
|
+
RetPE(); ///< place holder
|
|
545
|
+
RetPE(const RetPE &); ///< place holder
|
|
546
|
+
void operator=(const RetPE &); ///< place holder
|
|
547
|
+
|
|
548
|
+
const CallICFGNode* call; /// the callsite statement returning to
|
|
549
|
+
const FunExitICFGNode* exit; /// the function exit statement returned from
|
|
550
|
+
public:
|
|
551
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
552
|
+
//@{
|
|
553
|
+
static inline bool classof(const RetPE *)
|
|
554
|
+
{
|
|
555
|
+
return true;
|
|
556
|
+
}
|
|
557
|
+
static inline bool classof(const SVFStmt *edge)
|
|
558
|
+
{
|
|
559
|
+
return edge->getEdgeKind() == SVFStmt::Ret
|
|
560
|
+
|| edge->getEdgeKind() == SVFStmt::ThreadJoin;
|
|
561
|
+
}
|
|
562
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
563
|
+
{
|
|
564
|
+
return edge->getEdgeKind() == SVFStmt::Ret
|
|
565
|
+
|| edge->getEdgeKind() == SVFStmt::ThreadJoin;
|
|
566
|
+
}
|
|
567
|
+
//@}
|
|
568
|
+
|
|
569
|
+
/// constructor
|
|
570
|
+
RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e,
|
|
571
|
+
GEdgeKind k = SVFStmt::Ret);
|
|
572
|
+
|
|
573
|
+
/// Get method for call instruction at caller
|
|
574
|
+
//@{
|
|
575
|
+
inline const CallICFGNode* getCallInst() const
|
|
576
|
+
{
|
|
577
|
+
return call;
|
|
578
|
+
}
|
|
579
|
+
inline const CallICFGNode* getCallSite() const
|
|
580
|
+
{
|
|
581
|
+
return call;
|
|
582
|
+
}
|
|
583
|
+
inline const FunExitICFGNode* getFunExitICFGNode() const
|
|
584
|
+
{
|
|
585
|
+
return exit;
|
|
586
|
+
}
|
|
587
|
+
//@}
|
|
588
|
+
|
|
589
|
+
virtual const std::string toString() const override;
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
/*
|
|
593
|
+
* Program statements with multiple operands including BinaryOPStmt, CmpStmt and PhiStmt
|
|
594
|
+
*/
|
|
595
|
+
class MultiOpndStmt : public SVFStmt
|
|
596
|
+
{
|
|
597
|
+
public:
|
|
598
|
+
typedef std::vector<SVFVar*> OPVars;
|
|
599
|
+
private:
|
|
600
|
+
MultiOpndStmt(); ///< place holder
|
|
601
|
+
MultiOpndStmt(const MultiOpndStmt &); ///< place holder
|
|
602
|
+
void operator=(const MultiOpndStmt &); ///< place holder
|
|
603
|
+
SVFVar* getSrcNode(); ///< not allowed, use getOpVar(idx) instead
|
|
604
|
+
SVFVar* getDstNode(); ///< not allowed, use getRes() instead
|
|
605
|
+
NodeID getSrcID(); ///< not allowed, use getOpVarID(idx) instead
|
|
606
|
+
NodeID getDstID(); ///< not allowed, use getResID() instead
|
|
607
|
+
|
|
608
|
+
protected:
|
|
609
|
+
OPVars opVars;
|
|
610
|
+
/// Constructor, only used by subclassess but not external users
|
|
611
|
+
MultiOpndStmt(SVFVar* r, const OPVars& opnds, GEdgeFlag k);
|
|
612
|
+
public:
|
|
613
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
614
|
+
//@{
|
|
615
|
+
static inline bool classof(const MultiOpndStmt *)
|
|
616
|
+
{
|
|
617
|
+
return true;
|
|
618
|
+
}
|
|
619
|
+
static inline bool classof(const SVFStmt *node)
|
|
620
|
+
{
|
|
621
|
+
return node->getEdgeKind() == Phi ||
|
|
622
|
+
node->getEdgeKind() == Select ||
|
|
623
|
+
node->getEdgeKind() == BinaryOp ||
|
|
624
|
+
node->getEdgeKind() == Cmp;
|
|
625
|
+
}
|
|
626
|
+
static inline bool classof(const GenericPAGEdgeTy *node)
|
|
627
|
+
{
|
|
628
|
+
return node->getEdgeKind() == Phi ||
|
|
629
|
+
node->getEdgeKind() == Select ||
|
|
630
|
+
node->getEdgeKind() == BinaryOp ||
|
|
631
|
+
node->getEdgeKind() == Cmp;
|
|
632
|
+
}
|
|
633
|
+
//@}
|
|
634
|
+
/// Operands and result at a BinaryNode e.g., p = q + r, `p` is resVar and `r` is OpVar
|
|
635
|
+
//@{
|
|
636
|
+
/// Operand SVFVars
|
|
637
|
+
inline const SVFVar* getOpVar(u32_t pos) const
|
|
638
|
+
{
|
|
639
|
+
return opVars.at(pos);
|
|
640
|
+
}
|
|
641
|
+
/// Result SVFVar
|
|
642
|
+
inline const SVFVar* getRes() const
|
|
643
|
+
{
|
|
644
|
+
return SVFStmt::getDstNode();
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
NodeID getOpVarID(u32_t pos) const;
|
|
648
|
+
NodeID getResID() const;
|
|
649
|
+
|
|
650
|
+
inline u32_t getOpVarNum() const
|
|
651
|
+
{
|
|
652
|
+
return opVars.size();
|
|
653
|
+
}
|
|
654
|
+
inline const OPVars& getOpndVars() const
|
|
655
|
+
{
|
|
656
|
+
return opVars;
|
|
657
|
+
}
|
|
658
|
+
inline OPVars::const_iterator opVarBegin() const
|
|
659
|
+
{
|
|
660
|
+
return opVars.begin();
|
|
661
|
+
}
|
|
662
|
+
inline OPVars::const_iterator opVerEnd() const
|
|
663
|
+
{
|
|
664
|
+
return opVars.end();
|
|
665
|
+
}
|
|
666
|
+
//@}
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
/*!
|
|
670
|
+
* Phi statement (e.g., p = phi(q,r) which receives values from variables q and r from different paths)
|
|
671
|
+
* it is typically at a joint point of the control-flow graph
|
|
672
|
+
*/
|
|
673
|
+
class PhiStmt: public MultiOpndStmt
|
|
674
|
+
{
|
|
675
|
+
public:
|
|
676
|
+
typedef std::vector<const ICFGNode* > OpICFGNodeVec;
|
|
677
|
+
|
|
678
|
+
private:
|
|
679
|
+
PhiStmt(); ///< place holder
|
|
680
|
+
PhiStmt(const PhiStmt &); ///< place holder
|
|
681
|
+
void operator=(const PhiStmt &); ///< place holder
|
|
682
|
+
|
|
683
|
+
OpICFGNodeVec opICFGNodes;
|
|
684
|
+
public:
|
|
685
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
686
|
+
//@{
|
|
687
|
+
static inline bool classof(const PhiStmt *)
|
|
688
|
+
{
|
|
689
|
+
return true;
|
|
690
|
+
}
|
|
691
|
+
static inline bool classof(const SVFStmt *edge)
|
|
692
|
+
{
|
|
693
|
+
return edge->getEdgeKind() == SVFStmt::Phi;
|
|
694
|
+
}
|
|
695
|
+
static inline bool classof(const MultiOpndStmt *edge)
|
|
696
|
+
{
|
|
697
|
+
return edge->getEdgeKind() == SVFStmt::Phi;
|
|
698
|
+
}
|
|
699
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
700
|
+
{
|
|
701
|
+
return edge->getEdgeKind() == SVFStmt::Phi;
|
|
702
|
+
}
|
|
703
|
+
//@}
|
|
704
|
+
|
|
705
|
+
/// constructor
|
|
706
|
+
PhiStmt(SVFVar* s, const OPVars& opnds, const OpICFGNodeVec& icfgNodes) : MultiOpndStmt(s,opnds,SVFStmt::Phi), opICFGNodes(icfgNodes)
|
|
707
|
+
{
|
|
708
|
+
assert(opnds.size()==icfgNodes.size() && "Numbers of operands and their ICFGNodes are not consistent?");
|
|
709
|
+
}
|
|
710
|
+
void addOpVar(SVFVar* op, const ICFGNode* inode)
|
|
711
|
+
{
|
|
712
|
+
opVars.push_back(op);
|
|
713
|
+
opICFGNodes.push_back(inode);
|
|
714
|
+
assert(opVars.size()==opICFGNodes.size() && "Numbers of operands and their ICFGNodes are not consistent?");
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/// Return the corresponding ICFGNode of this operand
|
|
718
|
+
inline const ICFGNode* getOpICFGNode(u32_t op_idx) const
|
|
719
|
+
{
|
|
720
|
+
return opICFGNodes.at(op_idx);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/// Return true if this is a phi at the function exit
|
|
724
|
+
/// to receive one or multiple return values of this function
|
|
725
|
+
bool isFunctionRetPhi() const;
|
|
726
|
+
|
|
727
|
+
virtual const std::string toString() const override;
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
/*!
|
|
731
|
+
* Select statement (e.g., p ? q: r which receives values from variables q and r based on condition p)
|
|
732
|
+
*/
|
|
733
|
+
class SelectStmt: public MultiOpndStmt
|
|
734
|
+
{
|
|
735
|
+
private:
|
|
736
|
+
SelectStmt(); ///< place holder
|
|
737
|
+
SelectStmt(const SelectStmt &); ///< place holder
|
|
738
|
+
void operator=(const SelectStmt &); ///< place holder
|
|
739
|
+
|
|
740
|
+
const SVFVar* condition;
|
|
741
|
+
public:
|
|
742
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
743
|
+
//@{
|
|
744
|
+
static inline bool classof(const SelectStmt *)
|
|
745
|
+
{
|
|
746
|
+
return true;
|
|
747
|
+
}
|
|
748
|
+
static inline bool classof(const SVFStmt *edge)
|
|
749
|
+
{
|
|
750
|
+
return edge->getEdgeKind() == SVFStmt::Select;
|
|
751
|
+
}
|
|
752
|
+
static inline bool classof(const MultiOpndStmt *edge)
|
|
753
|
+
{
|
|
754
|
+
return edge->getEdgeKind() == SVFStmt::Select;
|
|
755
|
+
}
|
|
756
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
757
|
+
{
|
|
758
|
+
return edge->getEdgeKind() == SVFStmt::Select;
|
|
759
|
+
}
|
|
760
|
+
//@}
|
|
761
|
+
|
|
762
|
+
/// constructor
|
|
763
|
+
SelectStmt(SVFVar* s, const OPVars& opnds, const SVFVar* cond);
|
|
764
|
+
virtual const std::string toString() const override;
|
|
765
|
+
|
|
766
|
+
inline const SVFVar* getCondition() const
|
|
767
|
+
{
|
|
768
|
+
return condition;
|
|
769
|
+
}
|
|
770
|
+
inline const SVFVar* getTrueValue() const
|
|
771
|
+
{
|
|
772
|
+
return getOpVar(0);
|
|
773
|
+
}
|
|
774
|
+
inline const SVFVar* getFalseValue() const
|
|
775
|
+
{
|
|
776
|
+
return getOpVar(1);
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
/*!
|
|
781
|
+
* Comparison statement
|
|
782
|
+
*/
|
|
783
|
+
class CmpStmt: public MultiOpndStmt
|
|
784
|
+
{
|
|
785
|
+
private:
|
|
786
|
+
CmpStmt(); ///< place holder
|
|
787
|
+
CmpStmt(const CmpStmt &); ///< place holder
|
|
788
|
+
void operator=(const CmpStmt &); ///< place holder
|
|
789
|
+
|
|
790
|
+
u32_t predicate;
|
|
791
|
+
public:
|
|
792
|
+
|
|
793
|
+
/// OpCode for CmpStmt, enum value is same to llvm CmpInst
|
|
794
|
+
enum Predicate : unsigned
|
|
795
|
+
{
|
|
796
|
+
// Opcode U L G E Intuitive operation
|
|
797
|
+
FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded)
|
|
798
|
+
FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal
|
|
799
|
+
FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than
|
|
800
|
+
FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal
|
|
801
|
+
FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than
|
|
802
|
+
FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal
|
|
803
|
+
FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal
|
|
804
|
+
FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans)
|
|
805
|
+
FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
|
|
806
|
+
FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal
|
|
807
|
+
FCMP_UGT = 10, ///< 1 0 1 0 True if unordered or greater than
|
|
808
|
+
FCMP_UGE = 11, ///< 1 0 1 1 True if unordered, greater than, or equal
|
|
809
|
+
FCMP_ULT = 12, ///< 1 1 0 0 True if unordered or less than
|
|
810
|
+
FCMP_ULE = 13, ///< 1 1 0 1 True if unordered, less than, or equal
|
|
811
|
+
FCMP_UNE = 14, ///< 1 1 1 0 True if unordered or not equal
|
|
812
|
+
FCMP_TRUE = 15, ///< 1 1 1 1 Always true (always folded)
|
|
813
|
+
FIRST_FCMP_PREDICATE = FCMP_FALSE,
|
|
814
|
+
LAST_FCMP_PREDICATE = FCMP_TRUE,
|
|
815
|
+
BAD_FCMP_PREDICATE = FCMP_TRUE + 1,
|
|
816
|
+
ICMP_EQ = 32, ///< equal
|
|
817
|
+
ICMP_NE = 33, ///< not equal
|
|
818
|
+
ICMP_UGT = 34, ///< unsigned greater than
|
|
819
|
+
ICMP_UGE = 35, ///< unsigned greater or equal
|
|
820
|
+
ICMP_ULT = 36, ///< unsigned less than
|
|
821
|
+
ICMP_ULE = 37, ///< unsigned less or equal
|
|
822
|
+
ICMP_SGT = 38, ///< signed greater than
|
|
823
|
+
ICMP_SGE = 39, ///< signed greater or equal
|
|
824
|
+
ICMP_SLT = 40, ///< signed less than
|
|
825
|
+
ICMP_SLE = 41, ///< signed less or equal
|
|
826
|
+
FIRST_ICMP_PREDICATE = ICMP_EQ,
|
|
827
|
+
LAST_ICMP_PREDICATE = ICMP_SLE,
|
|
828
|
+
BAD_ICMP_PREDICATE = ICMP_SLE + 1
|
|
829
|
+
};
|
|
830
|
+
|
|
831
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
832
|
+
//@{
|
|
833
|
+
static inline bool classof(const CmpStmt *)
|
|
834
|
+
{
|
|
835
|
+
return true;
|
|
836
|
+
}
|
|
837
|
+
static inline bool classof(const SVFStmt *edge)
|
|
838
|
+
{
|
|
839
|
+
return edge->getEdgeKind() == SVFStmt::Cmp;
|
|
840
|
+
}
|
|
841
|
+
static inline bool classof(const MultiOpndStmt *edge)
|
|
842
|
+
{
|
|
843
|
+
return edge->getEdgeKind() == SVFStmt::Cmp;
|
|
844
|
+
}
|
|
845
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
846
|
+
{
|
|
847
|
+
return edge->getEdgeKind() == SVFStmt::Cmp;
|
|
848
|
+
}
|
|
849
|
+
//@}
|
|
850
|
+
|
|
851
|
+
/// constructor
|
|
852
|
+
CmpStmt(SVFVar* s, const OPVars& opnds, u32_t pre);
|
|
853
|
+
|
|
854
|
+
u32_t getPredicate() const
|
|
855
|
+
{
|
|
856
|
+
return predicate;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
virtual const std::string toString() const override;
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
/*!
|
|
864
|
+
* Binary statement
|
|
865
|
+
*/
|
|
866
|
+
class BinaryOPStmt: public MultiOpndStmt
|
|
867
|
+
{
|
|
868
|
+
private:
|
|
869
|
+
BinaryOPStmt(); ///< place holder
|
|
870
|
+
BinaryOPStmt(const BinaryOPStmt &); ///< place holder
|
|
871
|
+
void operator=(const BinaryOPStmt &); ///< place holder
|
|
872
|
+
u32_t opcode;
|
|
873
|
+
|
|
874
|
+
public:
|
|
875
|
+
/// OpCode for BinaryOPStmt, enum value is same to llvm BinaryOperator
|
|
876
|
+
enum OpCode: unsigned
|
|
877
|
+
{
|
|
878
|
+
Add = 13, FAdd = 14, Sub = 15, FSub = 16, Mul = 17, FMul = 18, UDiv = 19, SDiv = 20, FDiv = 21, URem = 22,
|
|
879
|
+
SRem = 23, FRem = 24, Shl = 25, LShr = 26, AShr = 27, And = 28, Or = 29, Xor = 30
|
|
880
|
+
};
|
|
881
|
+
|
|
882
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
883
|
+
//@{
|
|
884
|
+
static inline bool classof(const BinaryOPStmt *)
|
|
885
|
+
{
|
|
886
|
+
return true;
|
|
887
|
+
}
|
|
888
|
+
static inline bool classof(const SVFStmt *edge)
|
|
889
|
+
{
|
|
890
|
+
return edge->getEdgeKind() == SVFStmt::BinaryOp;
|
|
891
|
+
}
|
|
892
|
+
static inline bool classof(const MultiOpndStmt *edge)
|
|
893
|
+
{
|
|
894
|
+
return edge->getEdgeKind() == SVFStmt::BinaryOp;
|
|
895
|
+
}
|
|
896
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
897
|
+
{
|
|
898
|
+
return edge->getEdgeKind() == SVFStmt::BinaryOp;
|
|
899
|
+
}
|
|
900
|
+
//@}
|
|
901
|
+
|
|
902
|
+
/// constructor
|
|
903
|
+
BinaryOPStmt(SVFVar* s, const OPVars& opnds, u32_t oc);
|
|
904
|
+
|
|
905
|
+
u32_t getOpcode() const
|
|
906
|
+
{
|
|
907
|
+
return opcode;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
virtual const std::string toString() const override;
|
|
911
|
+
};
|
|
912
|
+
|
|
913
|
+
/*!
|
|
914
|
+
* Unary statement
|
|
915
|
+
*/
|
|
916
|
+
class UnaryOPStmt: public SVFStmt
|
|
917
|
+
{
|
|
918
|
+
private:
|
|
919
|
+
UnaryOPStmt(); ///< place holder
|
|
920
|
+
UnaryOPStmt(const UnaryOPStmt &); ///< place holder
|
|
921
|
+
void operator=(const UnaryOPStmt &); ///< place holder
|
|
922
|
+
SVFVar* getSrcNode(); ///< place holder, use getOpVar() instead
|
|
923
|
+
SVFVar* getDstNode(); ///< place holder, use getRes() instead
|
|
924
|
+
NodeID getSrcID(); ///< place holder, use getOpVarID(pos) instead
|
|
925
|
+
NodeID getDstID(); ///< place holder, use getResID() instead
|
|
926
|
+
|
|
927
|
+
u32_t opcode;
|
|
928
|
+
public:
|
|
929
|
+
/// OpCode for UnaryOPStmt, enum value is same to llvm::UnaryOperator
|
|
930
|
+
enum OpCode : unsigned
|
|
931
|
+
{
|
|
932
|
+
FNeg = 12
|
|
933
|
+
};
|
|
934
|
+
|
|
935
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
936
|
+
//@{
|
|
937
|
+
static inline bool classof(const UnaryOPStmt *)
|
|
938
|
+
{
|
|
939
|
+
return true;
|
|
940
|
+
}
|
|
941
|
+
static inline bool classof(const SVFStmt *edge)
|
|
942
|
+
{
|
|
943
|
+
return edge->getEdgeKind() == SVFStmt::UnaryOp;
|
|
944
|
+
}
|
|
945
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
946
|
+
{
|
|
947
|
+
return edge->getEdgeKind() == SVFStmt::UnaryOp;
|
|
948
|
+
}
|
|
949
|
+
//@}
|
|
950
|
+
|
|
951
|
+
/// constructor
|
|
952
|
+
UnaryOPStmt(SVFVar* s, SVFVar* d, u32_t oc) : SVFStmt(s,d,SVFStmt::UnaryOp), opcode(oc)
|
|
953
|
+
{
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
u32_t getOpcode() const
|
|
957
|
+
{
|
|
958
|
+
return opcode;
|
|
959
|
+
}
|
|
960
|
+
inline const SVFVar* getOpVar() const
|
|
961
|
+
{
|
|
962
|
+
return SVFStmt::getSrcNode();
|
|
963
|
+
}
|
|
964
|
+
inline const SVFVar* getRes() const
|
|
965
|
+
{
|
|
966
|
+
return SVFStmt::getDstNode();
|
|
967
|
+
}
|
|
968
|
+
NodeID getOpVarID() const;
|
|
969
|
+
NodeID getResID() const;
|
|
970
|
+
|
|
971
|
+
virtual const std::string toString() const override;
|
|
972
|
+
};
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
/*!
|
|
976
|
+
* Branch statements including if/else and switch
|
|
977
|
+
*/
|
|
978
|
+
class BranchStmt: public SVFStmt
|
|
979
|
+
{
|
|
980
|
+
public:
|
|
981
|
+
typedef std::vector<std::pair<const ICFGNode*, s32_t> > SuccAndCondPairVec;
|
|
982
|
+
private:
|
|
983
|
+
BranchStmt(); ///< place holder
|
|
984
|
+
BranchStmt(const BranchStmt &); ///< place holder
|
|
985
|
+
void operator=(const BranchStmt &); ///< place holder
|
|
986
|
+
SVFVar* getSrcNode(); ///< place holder, not allowed
|
|
987
|
+
SVFVar* getDstNode(); ///< place holder, not allowed
|
|
988
|
+
NodeID getSrcID(); ///< place holder, use getOpVarID(pos) instead
|
|
989
|
+
NodeID getDstID(); ///< place holder, use getResID() instead
|
|
990
|
+
|
|
991
|
+
SuccAndCondPairVec successors;
|
|
992
|
+
const SVFVar* cond;
|
|
993
|
+
const SVFVar* brInst;
|
|
994
|
+
|
|
995
|
+
public:
|
|
996
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
997
|
+
//@{
|
|
998
|
+
static inline bool classof(const BranchStmt *)
|
|
999
|
+
{
|
|
1000
|
+
return true;
|
|
1001
|
+
}
|
|
1002
|
+
static inline bool classof(const SVFStmt *edge)
|
|
1003
|
+
{
|
|
1004
|
+
return edge->getEdgeKind() == SVFStmt::Branch;
|
|
1005
|
+
}
|
|
1006
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
1007
|
+
{
|
|
1008
|
+
return edge->getEdgeKind() == SVFStmt::Branch;
|
|
1009
|
+
}
|
|
1010
|
+
//@}
|
|
1011
|
+
|
|
1012
|
+
/// constructor
|
|
1013
|
+
BranchStmt(SVFVar* inst, SVFVar* c, const SuccAndCondPairVec& succs) : SVFStmt(c,inst,SVFStmt::Branch), successors(succs), cond(c), brInst(inst)
|
|
1014
|
+
{
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/// The branch is unconditional if cond is a null value
|
|
1018
|
+
bool isUnconditional() const;
|
|
1019
|
+
/// The branch is conditional if cond is not a null value
|
|
1020
|
+
bool isConditional() const;
|
|
1021
|
+
/// Return the condition
|
|
1022
|
+
const SVFVar* getCondition() const;
|
|
1023
|
+
const SVFVar* getBranchInst() const
|
|
1024
|
+
{
|
|
1025
|
+
return brInst;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
/// For example if(c) {stmt1} else {stmt2}
|
|
1029
|
+
/// successor(0): stmt1, 1
|
|
1030
|
+
/// successor(1): stmt2, 0
|
|
1031
|
+
|
|
1032
|
+
/// For example switch(c) case 0: {stmt1; break;} case 1: {stmt2; break;} default {stmt3: break}
|
|
1033
|
+
/// successor(0): stmt1, 0
|
|
1034
|
+
/// successor(1): stmt2, 1
|
|
1035
|
+
/// successor(3): stmt3, -1
|
|
1036
|
+
|
|
1037
|
+
/// Successors of this branch statement
|
|
1038
|
+
///@{
|
|
1039
|
+
u32_t getNumSuccessors() const
|
|
1040
|
+
{
|
|
1041
|
+
return successors.size();
|
|
1042
|
+
}
|
|
1043
|
+
const SuccAndCondPairVec& getSuccessors() const
|
|
1044
|
+
{
|
|
1045
|
+
return successors;
|
|
1046
|
+
}
|
|
1047
|
+
const ICFGNode* getSuccessor (u32_t i) const
|
|
1048
|
+
{
|
|
1049
|
+
return successors.at(i).first;
|
|
1050
|
+
}
|
|
1051
|
+
s32_t getSuccessorCondValue (u32_t i) const
|
|
1052
|
+
{
|
|
1053
|
+
return successors.at(i).second;
|
|
1054
|
+
}
|
|
1055
|
+
//@}
|
|
1056
|
+
virtual const std::string toString() const override;
|
|
1057
|
+
};
|
|
1058
|
+
|
|
1059
|
+
|
|
1060
|
+
/*!
|
|
1061
|
+
* Thread Fork
|
|
1062
|
+
*/
|
|
1063
|
+
class TDForkPE: public CallPE
|
|
1064
|
+
{
|
|
1065
|
+
private:
|
|
1066
|
+
TDForkPE(); ///< place holder
|
|
1067
|
+
TDForkPE(const TDForkPE &); ///< place holder
|
|
1068
|
+
void operator=(const TDForkPE &); ///< place holder
|
|
1069
|
+
|
|
1070
|
+
public:
|
|
1071
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
1072
|
+
//@{
|
|
1073
|
+
static inline bool classof(const TDForkPE *)
|
|
1074
|
+
{
|
|
1075
|
+
return true;
|
|
1076
|
+
}
|
|
1077
|
+
static inline bool classof(const SVFStmt *edge)
|
|
1078
|
+
{
|
|
1079
|
+
return edge->getEdgeKind() == SVFStmt::ThreadFork;
|
|
1080
|
+
}
|
|
1081
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
1082
|
+
{
|
|
1083
|
+
return edge->getEdgeKind() == SVFStmt::ThreadFork;
|
|
1084
|
+
}
|
|
1085
|
+
//@}
|
|
1086
|
+
|
|
1087
|
+
/// constructor
|
|
1088
|
+
TDForkPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunEntryICFGNode* entry) :
|
|
1089
|
+
CallPE(s,d,i,entry,SVFStmt::ThreadFork)
|
|
1090
|
+
{
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
virtual const std::string toString() const;
|
|
1094
|
+
};
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
/*!
|
|
1099
|
+
* Thread Join
|
|
1100
|
+
*/
|
|
1101
|
+
class TDJoinPE: public RetPE
|
|
1102
|
+
{
|
|
1103
|
+
private:
|
|
1104
|
+
TDJoinPE(); ///< place holder
|
|
1105
|
+
TDJoinPE(const TDJoinPE &); ///< place holder
|
|
1106
|
+
void operator=(const TDJoinPE &); ///< place holder
|
|
1107
|
+
|
|
1108
|
+
public:
|
|
1109
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
1110
|
+
//@{
|
|
1111
|
+
static inline bool classof(const TDJoinPE *)
|
|
1112
|
+
{
|
|
1113
|
+
return true;
|
|
1114
|
+
}
|
|
1115
|
+
static inline bool classof(const SVFStmt *edge)
|
|
1116
|
+
{
|
|
1117
|
+
return edge->getEdgeKind() == SVFStmt::ThreadJoin;
|
|
1118
|
+
}
|
|
1119
|
+
static inline bool classof(const GenericPAGEdgeTy *edge)
|
|
1120
|
+
{
|
|
1121
|
+
return edge->getEdgeKind() == SVFStmt::ThreadJoin;
|
|
1122
|
+
}
|
|
1123
|
+
//@}
|
|
1124
|
+
|
|
1125
|
+
/// Constructor
|
|
1126
|
+
TDJoinPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e) :
|
|
1127
|
+
RetPE(s,d,i,e, SVFStmt::ThreadJoin)
|
|
1128
|
+
{
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
virtual const std::string toString() const;
|
|
1132
|
+
};
|
|
1133
|
+
|
|
1134
|
+
} // End namespace SVF
|
|
1135
|
+
|
|
1136
|
+
#endif /* INCLUDE_SVFIR_SVFSTATEMENT_H_ */
|