60 std::unique_ptr<SlicedTCT> tct(
97 std::vector<const CallGraphEdge*>
outEdges;
101 std::vector<const CallICFGNode*> directCalls;
102 std::vector<const CallICFGNode*> indirectCalls;
134 std::vector<const CallGraphEdge*>
forkEdges;
165 worklist.
push(start);
166 visited.insert(start);
167 while (!worklist.
empty())
171 std::vector<const CallGraphEdge*>
inEdges;
176 if (visited.insert(
caller).second)
221 if (!node->hasIncomingEdge())
267 std::vector<const CallGraphEdge*>
forkEdges;
288 std::vector<const CallGraphEdge*>
joinEdges;
302 : svfir(svfir), pta(pta), mhp(mhp), lockAnalysis(lockAnalysis), svfg(svfg)
392 SVFUtil::dyn_cast<CallICFGNode>(
forkSite);
409 assert(
svfg !=
nullptr &&
"data-dependence slice requires the thread-aware VFG_pre");
412 std::deque<const SVFGNode*> worklist;
429 if (
const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(stmt))
431 else if (
const StoreStmt* store = SVFUtil::dyn_cast<StoreStmt>(stmt))
432 addrPtr = store->getLHSVarID();
444 while (!worklist.empty())
446 const SVFGNode* node = worklist.front();
447 worklist.pop_front();
457 std::deque<const SVFGNode*>& worklist)
459 if (node !=
nullptr && visited.insert(node).second)
460 worklist.push_back(node);
471 SVFUtil::dyn_cast<StmtVFGNode>(node))
475 if (stmt !=
nullptr && stmt->getICFGNode() !=
nullptr)
476 result.insert(stmt->getICFGNode());
552 SVFUtil::dyn_cast<CallICFGNode>(
lockNode);
633 if (
callNode->getRetICFGNode() !=
nullptr)
639 if (
callNode->getRetICFGNode() !=
nullptr)
665 if (!exitBlock->getICFGNodeList().empty())
679 if (node !=
nullptr && node->getFun() !=
nullptr)
695 if (node !=
nullptr && node->
getFunction() !=
nullptr)
736 if (fun->hasBasicBlock())
759 inEdge->getIndirectCalls();
839 "ILA slice dropped a fork/join synchronization dependence");
845 "ILA slice dropped a lock/unlock synchronization dependence");
907 if (stmt !=
nullptr && stmt->getICFGNode() !=
nullptr)
AliasResult alias(const SVFVar *V1, const SVFVar *V2) override
Interface expose to users of our pointer analysis, given Value infos.
Set< const CallICFGNode * > CallInstSet
const FunObjVar * getFunction() const
Get function of this call node.
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
const ICFGNode * getThread() const
Return forksite.
bool push(const Data &data)
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
const SVFBasicBlock * getEntryBlock() const
const SVFBasicBlock * front() const
const SVFBasicBlock * getExitBB() const
iterator begin()
Iterators.
bool hasGNode(NodeID id) const
Has a node.
NodeType * getGNode(NodeID id) const
Get a node.
const GEdgeSetTy & getInEdges() const
std::list< const SVFStmt * > SVFStmtList
ICFGNodeIDToNodeMapTy::iterator iterator
FunExitICFGNode * getFunExitICFGNode(const FunObjVar *fun)
Add a function exit node.
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
Set< CxtLock > CxtLockSet
bool hasIntraLockSet(const ICFGNode *stmt) const
Set< CxtStmt > CxtStmtSet
bool isInsideCondIntraLock(const ICFGNode *stmt) const
Return true if a statement is inside a partial lock/unlock pair (conditional lock with unconditional ...
const InstSet & getIntraLockSet(const ICFGNode *stmt) const
const CxtLockSet & getCxtLockFromCxtStmt(const CxtStmt &cts) const
bool hasCxtStmtFromInst(const ICFGNode *inst) const
Context-sensitive statement and lock spans.
Set< const ICFGNode * > InstSet
const CxtStmtSet & getCxtStmtsFromInst(const ICFGNode *inst) const
bool hasCxtLockFromCxtStmt(const CxtStmt &cts) const
const InstSet & getCondIntraLockSet(const ICFGNode *stmt) const
ThreadCallGraph * getThreadCallGraph() const
Get ThreadCallGraph.
const CxtThreadStmtSet & getThreadStmtSet(const ICFGNode *inst) const
Get/has ThreadStmt.
bool hasThreadStmtSet(const ICFGNode *inst) const
TCT * getTCT() const
Get Thread Creation Tree.
OrderedSet< const CallICFGNode * > collectMutexStatements(const OrderedSet< const ICFGNode * > &sourceNodes)
std::pair< OrderedSet< const CallICFGNode * >, OrderedSet< const CallICFGNode * > > collectCommonThreadStatements(const OrderedSet< const ICFGNode * > &sourceNodes)
OrderedSet< const CallICFGNode * > collectPthreadStatements(const OrderedSet< const ICFGNode * > &sourceNodes)
OrderedSet< const VFGNode * > computeDataDependenceSVFGNodes(const OrderedSet< const SVFStmt * > &seeds, SVFG *svfg)
OrderedSet< const ICFGNode * > expandCallDependence(const OrderedSet< const ICFGNode * > &nodes)
OrderedSet< const ICFGNode * > getLockSet(const ICFGNode *node)
OrderedSet< const TCTNode * > getTCTNodeSetFromNode(const ICFGNode *node)
LockAnalysis * lockAnalysis
OrderedSet< const ICFGNode * > svfgNodesToICFGNodes(const OrderedSet< const VFGNode * > &nodes, const OrderedSet< const SVFStmt * > &seeds)
Project the retained VFG nodes (plus the seeds) onto their ICFG nodes.
static void enqueueSVFGNode(const SVFGNode *node, OrderedSet< const SVFGNode * > &visited, std::deque< const SVFGNode * > &worklist)
MTASlicerBase(SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, SVFG *svfg=nullptr)
SVFG * svfg
thread-aware VFG_pre (PTA/Single slicers; null for MTA)
void addSynchronizationDependencies(const OrderedSet< const CallICFGNode * > &pthreadCallNodes, const OrderedSet< const CallICFGNode * > &mutexCallNodes, OrderedSet< const ICFGNode * > &retainedNodes)
OrderedSet< const CallICFGNode * > getDependentThreadCreate(const ICFGNode *node)
bool preCandidateComputed
ValueFlowSlice preCandidateSlice
MultiStageSlicer(SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, SVFG *svfg=nullptr)
OrderedSet< const ICFGNode * > runILASlicing(const OrderedSet< const SVFStmt * > &vulnerableStatements, const OrderedSet< const ICFGNode * > &threadVFSources={})
const ValueFlowSlice & getPreCandidateSlice() const
Return the pre-candidate slice after computePreCandidateSlice().
void computePreCandidateSlice(const OrderedSet< const SVFStmt * > &vulnerableStatements)
ValueFlowSlice runPTASlicing(const OrderedSet< const SVFStmt * > &vulnerableStatements, SVFG *refinedMainVFG)
static const Option< bool > TCTDotGraph
CallGraph * getCallGraph() const
Return call graph.
bool hasDefSVFGNode(const ValVar *valVar) const
Given a valVar, return whether it has definition site.
const SVFGNode * getDefSVFGNode(const ValVar *valVar) const
Given a valVar, return its definition site.
NodeID getId() const
Get ID.
SingleSlicer(SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, SVFG *svfg=nullptr)
ValueFlowSlice runSlicing(const OrderedSet< const SVFStmt * > &vulnerableStatements)
void getKeptForkSites(std::vector< const ICFGNode * > &out) const
void collectEntryFunInCallGraph() override
Get entry functions that are neither called by other functions nor extern functions.
void collectLoopInfoForJoin() override
Handle join site in loop.
void handleCallRelation(CxtThreadProc &ctp, const CallGraphEdge *cgEdge, const CallICFGNode *cs) override
Handle call relations.
bool isKeptEdge(const CallGraphEdge *edge) const
void getKeptJoinSites(std::vector< const ICFGNode * > &out) const
bool isKeptNode(const CallGraphNode *node) const
const SlicedThreadCallGraphView & tcgView
static std::unique_ptr< SlicedTCT > create(PointerAnalysis &pointerAnalysis, const SlicedSVFIRView &slicedView, u32_t contextLimit)
void build() override
Build TCT.
void markRelProcs() override
Mark relevant procedures that are backward reachable from any fork/join site.
SlicedTCT(PointerAnalysis &pointerAnalysis, const SlicedSVFIRView &slicedView, u32_t contextLimit)
const OrderedSet< const CallGraphNode * > & getKeptNodes() const
Get all kept nodes.
void getDirectCallsOf(const CallGraphEdge *edge, std::vector< const CallICFGNode * > &out) const
Retained callsites carried by an aggregated call-graph edge.
bool isKeptNode(const CallGraphNode *node) const
Check if a node is in the sliced view.
void getIndirectCallsOf(const CallGraphEdge *edge, std::vector< const CallICFGNode * > &out) const
bool isKeptEdge(const CallGraphEdge *e) const
void getOutEdgesOf(const CallGraphNode *node, std::vector< const CallGraphEdge * > &out) const
Get out edges of a node (only returns kept edges and target nodes)
void getInEdgesOf(const CallGraphNode *node, std::vector< const CallGraphEdge * > &out) const
Get in edges of a node (only returns kept edges and source nodes)
const CxtThread & getCxtThread() const
Get thread creation context, <fork site, call string context>
bool pushToCTPWorkList(const CxtThreadProc &ctp)
WorkList helper functions.
const FunSet & getMakredProcs() const
Get marked candidate functions.
const NodeBS getAncestorThreads(NodeID tid) const
Get all ancestor threads.
bool isInRecursion(const ICFGNode *inst) const
Whether an instruction is in a recursion.
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
TCTNode * getOrCreateTCTNode(const CallStrCxt &cxt, const ICFGNode *fork, const CxtThreadProc &forkSiteCtp, const FunObjVar *routine)
Get or create a tct node based on CxtThread.
Set< const CallGraphNode * > PTACGNodeSet
ICFGNode * createDummyForkSite()
Create and get a new dummy fork site for starter routines.
InstToLoopMap joinSiteToLoopMap
Map a CxtThread to its start routine function.
void dump(const std::string &filename)
Dump the graph.
FunSet candidateFuncSet
Procedures that are neither called by other functions nor extern functions.
bool isCandidateFun(const CallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
CxtThreadProcVec ctpList
Thread call graph SCC.
bool isJoinMustExecutedInLoop(const LoopBBs &lp, const ICFGNode *join)
Return true if a join instruction must be executed inside a loop.
Set< const ICFGNode * > inRecurJoinSites
Fork or Join sites in recursions.
const FunSet & getEntryProcs() const
Get marked candidate functions.
void print() const
Print TCT information.
virtual void handleCallRelation(CxtThreadProc &ctp, const CallGraphEdge *cgEdge, const CallICFGNode *call)
Handle call relations.
void collectMultiForkedThreads()
CxtThreadProc popFromCTPWorkList()
SVFLoopAndDomInfo::LoopBBs LoopBBs
CallSiteSet::const_iterator forksitesEnd() const
CallSiteSet::const_iterator forksitesBegin() const
Fork sites iterators.
CallSiteSet::const_iterator joinsitesEnd() const
CallSiteSet::const_iterator joinsitesBegin() const
Join sites iterators.
ThreadAPI * getThreadAPI() const
Thread API.
bool hasStmtVFGNode(const SVFStmt *svfStmt) const
Existence checks for VFGNodes.
StmtVFGNode * getStmtVFGNode(const SVFStmt *svfStmt) const
Get an VFGNode.
bool isExtCall(const FunObjVar *fun)
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
llvm::IRBuilder IRBuilder
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
std::vector< u32_t > CallStrCxt
OrderedSet< const SVFGNode * > svfgNodes
OrderedSet< const ICFGNode * > icfgNodes