Static Value-Flow Analysis
Loading...
Searching...
No Matches
SVF::MTA Class Reference

#include <MTA.h>

Classes

struct  RacePair
 A race pair: two statements that may race. More...
struct  RaceOccurrence
 One occurrence of a memory access under one thread instance. More...
struct  RaceClass
struct  RaceClassKey

Public Member Functions

 MTA ()
 Constructor.
virtual ~MTA ()
 Destructor.
virtual bool runOnModule (SVFIR *module)
 We start the pass here.
virtual MHP * computeMHP (TCT *tct)
 Compute MHP.
virtual LockAnalysis * computeLocksets (TCT *tct)
 Compute locksets.
virtual void reportRaces ()
 Run the shared detector and print a race report.
MHP * getMHP ()
LockAnalysis * getLockAnalysis ()

Static Public Member Functions

static std::set< const SVFStmt * > detectRace (SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, CallGraph *callGraph, std::set< RacePair > &outRacePairs)
static PointsTo getGlobalObjectVariables (SVFIR *svfir)
 Escape/points-to helpers for the shared detector.
static PointsTo getPointsToClosure (AndersenBase *pta, const PointsTo &pts)
static bool hasThreadFunctions (CallGraph *callGraph)

Private Types

using ObjectToRaceOccurrences = Map<NodeID, std::vector<size_t>>

Static Private Member Functions

static void collectRaceOccurrences (SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, CallGraph *callGraph, const PointsTo &escapedObjects, std::vector< RaceOccurrence > &occurrences, ObjectToRaceOccurrences &objectToOccurrences)
 Helpers for the equivalence-class race detector.
static std::vector< RaceClass > buildRaceClasses (const std::vector< RaceOccurrence > &occurrences, const std::vector< size_t > &occurrenceIndices)
static void emitRacePairs (MHP *mhp, LockAnalysis *lockAnalysis, const std::vector< RaceOccurrence > &occurrences, const std::vector< RaceClass > &classes, std::set< RacePair > &outRacePairs)
static bool occurrencesRace (MHP *mhp, const RaceOccurrence &first, const RaceOccurrence &second)
static void commitRacePair (std::set< RacePair > &out, const RaceOccurrence &first, const RaceOccurrence &second)

Private Attributes

ThreadCallGraph * tcg
std::unique_ptr< TCT > tct
std::unique_ptr< MTAStat > stat
MHP * mhp
LockAnalysis * lsa

Detailed Description

Base data race detector

Definition at line 80 of file MTA.h.

Member Typedef Documentation

◆ ObjectToRaceOccurrences

using SVF::MTA::ObjectToRaceOccurrences = Map<NodeID, std::vector<size_t>>
private

Definition at line 179 of file MTA.h.

Constructor & Destructor Documentation

◆ MTA()

MTA::MTA ( )

Constructor.

Definition at line 53 of file MTA.cpp.

53 : tcg(nullptr), tct(nullptr), mhp(nullptr), lsa(nullptr)
54{
55 stat = std::make_unique<MTAStat>();
56}
ThreadCallGraph * tcg
Definition MTA.h:202
std::unique_ptr< TCT > tct
Definition MTA.h:203
LockAnalysis * lsa
Definition MTA.h:206
MHP * mhp
Definition MTA.h:205
std::unique_ptr< MTAStat > stat
Definition MTA.h:204

◆ ~MTA()

MTA::~MTA ( )
virtual

Destructor.

Definition at line 58 of file MTA.cpp.

59{
60 delete mhp;
61 delete lsa;
62}

Member Function Documentation

◆ buildRaceClasses()

std::vector< MTA::RaceClass > MTA::buildRaceClasses ( const std::vector< RaceOccurrence > & occurrences,
const std::vector< size_t > & occurrenceIndices )
staticprivate

Definition at line 289 of file MTA.cpp.

292{
293 std::vector<RaceClass> classes;
295 for (size_t occurrenceIndex : occurrenceIndices)
296 {
297 const RaceOccurrence& occurrence = occurrences[occurrenceIndex];
298 const RaceClassKey key
299 {
300 occurrence.tid, occurrence.isStore, occurrence.interleaving,
301 occurrence.locked,
302 occurrence.locked ? occurrence.node->getId() : 0};
303 const auto found = keyToClass.find(key);
304 if (found == keyToClass.end())
305 {
306 keyToClass[key] = classes.size();
307 classes.push_back(
308 {
309 occurrence.isStore, occurrence.locked, occurrenceIndex,
310 {occurrenceIndex}});
311 }
312 else
313 classes[found->second].members.push_back(occurrenceIndex);
314 }
315 return classes;
316}
std::map< Key, Value, Compare, Allocator > OrderedMap
Definition GeneralType.h:64
One occurrence of a memory access under one thread instance.
Definition MTA.h:151

◆ collectRaceOccurrences()

void MTA::collectRaceOccurrences ( SVFIR * svfir,
AndersenBase * pta,
MHP * mhp,
LockAnalysis * lockAnalysis,
CallGraph * callGraph,
const PointsTo & escapedObjects,
std::vector< RaceOccurrence > & occurrences,
ObjectToRaceOccurrences & objectToOccurrences )
staticprivate

Helpers for the equivalence-class race detector.

Definition at line 229 of file MTA.cpp.

235{
236 for (const auto& item : *callGraph)
237 {
238 const FunObjVar* fun = item.second->getFunction();
239 if (!fun || !fun->hasBasicBlock())
240 continue;
241 for (auto bbIt : *fun)
242 for (const ICFGNode* node : bbIt.second->getICFGNodeList())
243 {
244 const MHP::NodeThreadSummary* threadSummary =
245 mhp->getThreadSummary(node);
246 if (threadSummary == nullptr)
247 continue;
248 for (const SVFStmt* stmt : svfir->getSVFStmtList(node))
249 {
250 NodeID accessedPtr;
251 bool isStore;
252 if (const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(stmt))
253 {
254 accessedPtr = load->getRHSVarID();
255 isStore = false;
256 }
257 else if (const StoreStmt* store =
259 {
260 accessedPtr = store->getLHSVarID();
261 isStore = true;
262 }
263 else
264 continue;
265
266 PointsTo objects = pta->getPts(accessedPtr);
267 objects &= escapedObjects;
268 if (objects.empty())
269 continue;
270
271 const bool locked =
272 lockAnalysis->isProtectedByCommonLock(node, node);
273 const size_t firstNewOccurrence = occurrences.size();
274 for (const auto& tidAndInterleaving :
275 threadSummary->interleavingByTid)
276 occurrences.push_back(
277 {
278 stmt, node, isStore, tidAndInterleaving.first,
279 &tidAndInterleaving.second, locked});
280 for (NodeID object : objects)
281 for (size_t index = firstNewOccurrence;
282 index < occurrences.size(); ++index)
283 objectToOccurrences[object].push_back(index);
284 }
285 }
286 }
287}
int index
Definition cJSON.h:170
cJSON * item
Definition cJSON.h:222
const PointsTo & getPts(NodeID id) override
bool hasBasicBlock() const
bool isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2)
bool empty() const
Returns true if set is empty.
Definition PointsTo.cpp:110
SVFStmtList & getSVFStmtList(const ICFGNode *inst)
Given an instruction, get all its PAGEdges.
Definition SVFIR.h:319
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition Casting.h:405
u32_t NodeID
Definition GeneralType.h:76
Map< NodeID, NodeBS > interleavingByTid
Definition MHP.h:68

◆ commitRacePair()

void MTA::commitRacePair ( std::set< RacePair > & out,
const RaceOccurrence & first,
const RaceOccurrence & second )
staticprivate

Definition at line 207 of file MTA.cpp.

210{
211 out.emplace(first.stmt, second.stmt);
212}

◆ computeLocksets()

LockAnalysis * MTA::computeLocksets ( TCT * tct)
virtual

Compute locksets.

Compute lock sets

Definition at line 106 of file MTA.cpp.

107{
108 LockAnalysis* lsa = new LockAnalysis(tct);
109 lsa->analyze(PAG::getPAG()->getICFG(), const_cast<CallGraph*>(PAG::getPAG()->getCallGraph()));
110 return lsa;
111}
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:121

◆ computeMHP()

MHP * MTA::computeMHP ( TCT * tct)
virtual

Compute MHP.

Definition at line 113 of file MTA.cpp.

114{
115 DBOUT(DGENERAL, outs() << pasMsg("MHP analysis\n"));
116 DBOUT(DMTA, outs() << pasMsg("MHP analysis\n"));
117
118 DOTIMESTAT(double mhpStart = stat->getClk());
119 std::unique_ptr<MHP> mhp = MHP::create(
120 tct, PAG::getPAG()->getICFG(),
121 const_cast<CallGraph*>(PAG::getPAG()->getCallGraph()));
122 mhp->analyze(PAG::getPAG()->getICFG(), const_cast<CallGraph*>(PAG::getPAG()->getCallGraph()));
123 DOTIMESTAT(double mhpEnd = stat->getClk());
124 DOTIMESTAT(stat->MHPTime += (mhpEnd - mhpStart) / TIMEINTERVAL);
125
126 DBOUT(DGENERAL, outs() << pasMsg("MHP analysis finish\n"));
127 DBOUT(DMTA, outs() << pasMsg("MHP analysis finish\n"));
128 return mhp.release();
129}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define TIMEINTERVAL
Definition SVFType.h:604
#define DMTA
Definition SVFType.h:597
#define DGENERAL
Definition SVFType.h:582
#define DOTIMESTAT(X)
Definition SVFType.h:578
static std::unique_ptr< MHP > create(TCT *t, ICFGGraph icfg, CGGraph cg, StateRepresentation representation=StateRepresentation::MaterializedContexts)
Construct MHP and initialize its graph-dependent ForkJoinAnalysis.
Definition MHP.h:646
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:121
std::ostream & outs()
Overwrite llvm::outs().
Definition SVFUtil.h:58

◆ detectRace()

std::set< const SVFStmt * > MTA::detectRace ( SVFIR * svfir,
AndersenBase * pta,
MHP * mhp,
LockAnalysis * lockAnalysis,
CallGraph * callGraph,
std::set< RacePair > & outRacePairs )
static

Shared equivalence-class race detector (used by both MTA::reportRaces and the SlicedMTA pipeline). Returns the racy statements and fills outRacePairs.

Definition at line 372 of file MTA.cpp.

376{
377
378 outRacePairs.clear();
379 std::set<const SVFStmt*> bugStmts;
380
381 // Escape set: objects shared across threads. Seed from globals + the actual
382 // argument at each fork site (the spawner's value, which a spawnee-formal
383 // closure can miss), then take the transitive points-to closure.
384 PointsTo seed = getGlobalObjectVariables(svfir);
385 if (ThreadCallGraph* tcg = SVFUtil::dyn_cast<ThreadCallGraph>(callGraph))
386 {
387 const ThreadAPI* tapi = tcg->getThreadAPI();
388 for (auto it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; ++it)
389 if (const CallICFGNode* cs = SVFUtil::dyn_cast<CallICFGNode>(*it))
390 if (const ValVar* actual = tapi->getActualParmAtForkSite(cs))
391 seed |= pta->getPts(actual->getId());
392 }
393 const PointsTo escSet = getPointsToClosure(pta, seed);
394
395 std::vector<RaceOccurrence> occurrences;
396 ObjectToRaceOccurrences objectToOccurrences;
398 svfir, pta, mhp, lockAnalysis, callGraph, escSet,
399 occurrences, objectToOccurrences);
400
401 // Within each object, occurrences sharing the race predicate's inputs (tid,
402 // interleaving, isStore, lock sig) race the same partners, so collapse into a
403 // class and judge C2/C3/C4 once per class pair -- O(classes^2) not O(occ^2).
404 for (const auto& objectAndOccs : objectToOccurrences)
405 {
406 const std::vector<RaceClass> classes =
407 buildRaceClasses(occurrences, objectAndOccs.second);
409 mhp, lockAnalysis, occurrences, classes, outRacePairs);
410 }
411
412 for (const RacePair& pair : outRacePairs)
413 {
414 bugStmts.insert(pair.stmt1);
415 bugStmts.insert(pair.stmt2);
416 }
417 return bugStmts;
418}
static void emitRacePairs(MHP *mhp, LockAnalysis *lockAnalysis, const std::vector< RaceOccurrence > &occurrences, const std::vector< RaceClass > &classes, std::set< RacePair > &outRacePairs)
Definition MTA.cpp:318
static std::vector< RaceClass > buildRaceClasses(const std::vector< RaceOccurrence > &occurrences, const std::vector< size_t > &occurrenceIndices)
Definition MTA.cpp:289
Map< NodeID, std::vector< size_t > > ObjectToRaceOccurrences
Definition MTA.h:179
static PointsTo getGlobalObjectVariables(SVFIR *svfir)
Escape/points-to helpers for the shared detector.
Definition MTA.cpp:132
static void collectRaceOccurrences(SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, CallGraph *callGraph, const PointsTo &escapedObjects, std::vector< RaceOccurrence > &occurrences, ObjectToRaceOccurrences &objectToOccurrences)
Helpers for the equivalence-class race detector.
Definition MTA.cpp:229
static PointsTo getPointsToClosure(AndersenBase *pta, const PointsTo &pts)
Definition MTA.cpp:161
const ValVar * getActualParmAtForkSite(const CallICFGNode *inst) const
A race pair: two statements that may race.
Definition MTA.h:112

◆ emitRacePairs()

void MTA::emitRacePairs ( MHP * mhp,
LockAnalysis * lockAnalysis,
const std::vector< RaceOccurrence > & occurrences,
const std::vector< RaceClass > & classes,
std::set< RacePair > & outRacePairs )
staticprivate

Definition at line 318 of file MTA.cpp.

323{
324 for (size_t firstIndex = 0; firstIndex < classes.size(); ++firstIndex)
325 for (size_t secondIndex = firstIndex;
326 secondIndex < classes.size(); ++secondIndex)
327 {
328 const RaceClass& firstClass = classes[firstIndex];
329 const RaceClass& secondClass = classes[secondIndex];
330 if (!firstClass.isStore && !secondClass.isStore)
331 continue;
332
333 const RaceOccurrence& firstRepresentative =
334 occurrences[firstClass.representative];
335 const RaceOccurrence& secondRepresentative =
336 occurrences[secondClass.representative];
337 if (!occurrencesRace(
338 mhp, firstRepresentative, secondRepresentative))
339 continue;
340
341 if (firstIndex != secondIndex)
342 {
343 if (firstClass.locked && secondClass.locked &&
344 lockAnalysis->isProtectedByCommonLock(
345 firstRepresentative.node, secondRepresentative.node))
346 continue;
347 for (size_t memberIndex : firstClass.members)
348 for (size_t otherIndex : secondClass.members)
349 commitRacePair(outRacePairs, occurrences[memberIndex],
350 occurrences[otherIndex]);
351 }
352 else
353 {
354 const std::vector<size_t>& members = firstClass.members;
355 if (firstClass.locked &&
356 lockAnalysis->isProtectedByCommonLock(
357 firstRepresentative.node, firstRepresentative.node))
358 continue;
359 for (size_t firstPosition = 0;
360 firstPosition < members.size(); ++firstPosition)
361 for (size_t secondPosition = firstPosition;
362 secondPosition < members.size(); ++secondPosition)
364 outRacePairs, occurrences[members[firstPosition]],
365 occurrences[members[secondPosition]]);
366 }
367 }
368}
static bool occurrencesRace(MHP *mhp, const RaceOccurrence &first, const RaceOccurrence &second)
Definition MTA.cpp:197
static void commitRacePair(std::set< RacePair > &out, const RaceOccurrence &first, const RaceOccurrence &second)
Definition MTA.cpp:207

◆ getGlobalObjectVariables()

PointsTo MTA::getGlobalObjectVariables ( SVFIR * svfir)
static

Escape/points-to helpers for the shared detector.

Definition at line 132 of file MTA.cpp.

133{
134 PointsTo globalObjVars;
135 const ICFGNode* globalICFGNode = svfir->getICFG()->getGlobalICFGNode();
136
137 for (const SVFStmt* stmt : globalICFGNode->getSVFStmts())
138 {
139 const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt);
140 if (addrStmt != nullptr)
141 {
142 const GlobalValVar* globalVar =
144 if (globalVar != nullptr)
145 {
146 globalObjVars.set(addrStmt->getRHSVarID());
147 }
148 }
149 }
150
151 return globalObjVars;
152}
const ValVar * getLHSVar() const
NodeID getRHSVarID() const
const SVFStmtList & getSVFStmts() const
Definition ICFGNode.h:116
GlobalICFGNode * getGlobalICFGNode() const
Definition ICFG.h:244
void set(u32_t n)
Inserts n in the set.
Definition PointsTo.cpp:169
ICFG * getICFG() const
Definition SVFIR.h:232

◆ getLockAnalysis()

LockAnalysis * SVF::MTA::getLockAnalysis ( )
inline

Definition at line 105 of file MTA.h.

106 {
107 return lsa;
108 }

◆ getMHP()

MHP * SVF::MTA::getMHP ( )
inline

Definition at line 100 of file MTA.h.

101 {
102 return mhp;
103 }

◆ getPointsToClosure()

PointsTo MTA::getPointsToClosure ( AndersenBase * pta,
const PointsTo & pts )
static

Definition at line 161 of file MTA.cpp.

162{
163 SVFIR* pag = pta->getPAG();
164 PointsTo ptsClosure = pts;
165 std::deque<NodeID> worklist;
166 for (NodeID pt : pts)
167 {
168 worklist.push_back(pt);
169 }
170
171 while (!worklist.empty())
172 {
173 NodeID obj = worklist.front();
174 worklist.pop_front();
175
176 for (NodeID target : pta->getPts(obj)) // points-to
177 if (!ptsClosure.test(target))
178 {
179 ptsClosure.set(target);
180 worklist.push_back(target);
181 }
182
183 if (pag->getBaseObject(obj) != nullptr) // containment (object nodes only)
184 for (NodeID field : pta->getAllFieldsObjVars(pta->getBaseObjVarID(obj)))
185 if (!ptsClosure.test(field))
186 {
187 ptsClosure.set(field);
188 worklist.push_back(field);
189 }
190 }
191
192 return ptsClosure;
193}
NodeID getBaseObjVarID(NodeID id)
SVFIR * getPAG() const
virtual const NodeBS & getAllFieldsObjVars(NodeID id)
bool test(u32_t n) const
Returns true if n is in this set.
Definition PointsTo.cpp:143
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:499

◆ hasThreadFunctions()

bool MTA::hasThreadFunctions ( CallGraph * callGraph)
static

Whether the program has any thread (fork-target) function reachable via a fork edge.

Definition at line 1326 of file MTA.cpp.

1327{
1328 for (CallGraph::iterator it = callGraph->begin(), eit = callGraph->end();
1329 it != eit; ++it)
1330 {
1331 const CallGraphNode* node = it->second;
1332 for (const CallGraphEdge* edge : node->getOutEdges())
1333 {
1334 if (edge->getEdgeKind() == CallGraphEdge::TDForkEdge &&
1335 edge->getDstNode()->getFunction() != nullptr)
1336 {
1337 return true;
1338 }
1339 }
1340 }
1341 return false;
1342}
iterator begin()
Iterators.
const GEdgeSetTy & getOutEdges() const

◆ occurrencesRace()

bool MTA::occurrencesRace ( MHP * mhp,
const RaceOccurrence & first,
const RaceOccurrence & second )
staticprivate

Definition at line 197 of file MTA.cpp.

199{
200 if (first.tid != second.tid)
201 return first.interleaving->test(second.tid) &&
202 second.interleaving->test(first.tid);
203 return mhp->getTCT()->getTCTNode(first.tid)->isMultiforked();
204}

◆ reportRaces()

void MTA::reportRaces ( )
virtual

Run the shared detector and print a race report.

Definition at line 420 of file MTA.cpp.

421{
422 DBOUT(DGENERAL, outs() << pasMsg("Starting Race Detection\n"));
423
424 SVFIR* pag = SVFIR::getPAG();
425 AndersenBase* pta = AndersenWaveDiff::createAndersenWaveDiff(pag);
426 CallGraph* callGraph = pta->getCallGraph();
427
428 // Shared equivalence-class detector (the same one the slicing pipeline uses),
429 // run over the Andersen pre-analysis with this MTA's MHP/lock results.
430 std::set<RacePair> racePairs;
431 detectRace(pag, pta, mhp, lsa, callGraph, racePairs);
432
433 for (const RacePair& rp : racePairs)
434 outs() << SVFUtil::bugMsg1("race pair(") << " stmt1: " << rp.stmt1->toString()
435 << ", stmt2: " << rp.stmt2->toString() << SVFUtil::bugMsg1(")") << "\n";
436}
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition Andersen.h:430
static std::set< const SVFStmt * > detectRace(SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, CallGraph *callGraph, std::set< RacePair > &outRacePairs)
Definition MTA.cpp:372
CallGraph * getCallGraph() const
Return call graph.
std::string bugMsg1(const std::string &msg)
Definition SVFUtil.cpp:103

◆ runOnModule()

bool MTA::runOnModule ( SVFIR * pag)
virtual

We start the pass here.

Perform data race detection

Definition at line 67 of file MTA.cpp.

68{
69 DBOUT(DGENERAL, outs() << pasMsg("MTA analysis\n"));
70 DBOUT(DMTA, outs() << pasMsg("MTA analysis\n"));
71
72 PointerAnalysis* pta = AndersenWaveDiff::createAndersenWaveDiff(pag);
74 pta->getCallGraph()->dump("ptacg");
75 pag->getICFG()->updateCallGraph(pta->getCallGraph());
76
77 DBOUT(DGENERAL, outs() << pasMsg("Build TCT\n"));
78 DBOUT(DMTA, outs() << pasMsg("Build TCT\n"));
79 DOTIMESTAT(double tctStart = stat->getClk());
80 tct = TCT::create(pta);
81 tcg = tct->getThreadCallGraph();
82 DOTIMESTAT(double tctEnd = stat->getClk());
83 DOTIMESTAT(stat->TCTTime += (tctEnd - tctStart) / TIMEINTERVAL);
84
85 if (pta->printStat())
86 {
87 stat->performThreadCallGraphStat(tcg);
88 stat->performTCTStat(tct.get());
89 }
90
92 tcg->dump("tcg");
93
94 mhp = computeMHP(tct.get());
95 lsa = computeLocksets(tct.get());
96
97 // MTA's only client is race detection; always report.
99
100 return false;
101}
void dump(const std::string &filename)
Dump the graph.
void updateCallGraph(CallGraph *callgraph)
update ICFG for indirect calls
Definition ICFG.cpp:428
virtual LockAnalysis * computeLocksets(TCT *tct)
Compute locksets.
Definition MTA.cpp:106
virtual MHP * computeMHP(TCT *tct)
Compute MHP.
Definition MTA.cpp:113
virtual void reportRaces()
Run the shared detector and print a race report.
Definition MTA.cpp:420
static const Option< bool > DumpMTAGraphs
MTA: dump the pointer-analysis and thread call graphs (ptacg/tcg.dot), Default: false.
Definition Options.h:260
bool printStat()
Whether print statistics.
static std::unique_ptr< TCT > create(PointerAnalysis *p)
Construct and build a TCT with the command-line context bound.
Definition TCT.cpp:41

Member Data Documentation

◆ lsa

LockAnalysis* SVF::MTA::lsa
private

Definition at line 206 of file MTA.h.

◆ mhp

MHP* SVF::MTA::mhp
private

Definition at line 205 of file MTA.h.

◆ stat

std::unique_ptr<MTAStat> SVF::MTA::stat
private

Definition at line 204 of file MTA.h.

◆ tcg

ThreadCallGraph* SVF::MTA::tcg
private

Definition at line 202 of file MTA.h.

◆ tct

std::unique_ptr<TCT> SVF::MTA::tct
private

Definition at line 203 of file MTA.h.


The documentation for this class was generated from the following files: