void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { const CFGBlock *Blk = L.getDst(); NodeBuilderContext BuilderCtx(*this, Blk, Pred); // Mark this block as visited. const LocationContext *LC = Pred->getLocationContext(); FunctionSummaries->markVisitedBasicBlock(Blk->getBlockID(), LC->getDecl(), LC->getCFG()->getNumBlockIDs()); // Check if we are entering the EXIT block. if (Blk == &(L.getLocationContext()->getCFG()->getExit())) { assert(L.getLocationContext()->getCFG()->getExit().empty() && "EXIT block cannot contain Stmts."); // Get return statement.. const ReturnStmt *RS = nullptr; if (!L.getSrc()->empty()) { CFGElement LastElement = L.getSrc()->back(); if (Optional<CFGStmt> LastStmt = LastElement.getAs<CFGStmt>()) { RS = dyn_cast<ReturnStmt>(LastStmt->getStmt()); } else if (Optional<CFGAutomaticObjDtor> AutoDtor = LastElement.getAs<CFGAutomaticObjDtor>()) { RS = dyn_cast<ReturnStmt>(AutoDtor->getTriggerStmt()); } } // Process the final state transition. SubEng.processEndOfFunction(BuilderCtx, Pred, RS); // This path is done. Don't enqueue any more nodes. return; } // Call into the SubEngine to process entering the CFGBlock. ExplodedNodeSet dstNodes; BlockEntrance BE(Blk, Pred->getLocationContext()); NodeBuilderWithSinks nodeBuilder(Pred, dstNodes, BuilderCtx, BE); SubEng.processCFGBlockEntrance(L, nodeBuilder, Pred); // Auto-generate a node. if (!nodeBuilder.hasGeneratedNodes()) { nodeBuilder.generateNode(Pred->State, Pred); } // Enqueue nodes onto the worklist. enqueue(dstNodes); }
void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { const CFGBlock *Blk = L.getDst(); // Check if we are entering the EXIT block. if (Blk == &(L.getLocationContext()->getCFG()->getExit())) { assert (L.getLocationContext()->getCFG()->getExit().size() == 0 && "EXIT block cannot contain Stmts."); // Process the final state transition. EndOfFunctionNodeBuilder Builder(Blk, Pred, this); SubEng.processEndOfFunction(Builder); // This path is done. Don't enqueue any more nodes. return; } // Call into the subengine to process entering the CFGBlock. ExplodedNodeSet dstNodes; BlockEntrance BE(Blk, Pred->getLocationContext()); GenericNodeBuilder<BlockEntrance> nodeBuilder(*this, Pred, BE); SubEng.processCFGBlockEntrance(dstNodes, nodeBuilder); if (dstNodes.empty()) { if (!nodeBuilder.hasGeneratedNode) { // Auto-generate a node and enqueue it to the worklist. generateNode(BE, Pred->State, Pred); } } else { for (ExplodedNodeSet::iterator I = dstNodes.begin(), E = dstNodes.end(); I != E; ++I) { WList->enqueue(*I); } } for (SmallVectorImpl<ExplodedNode*>::const_iterator I = nodeBuilder.sinks().begin(), E = nodeBuilder.sinks().end(); I != E; ++I) { blocksExhausted.push_back(std::make_pair(L, *I)); } }
void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { const CFGBlock *Blk = L.getDst(); NodeBuilderContext BuilderCtx(*this, Blk, Pred); // Mark this block as visited. const LocationContext *LC = Pred->getLocationContext(); FunctionSummaries->markVisitedBasicBlock(Blk->getBlockID(), LC->getDecl(), LC->getCFG()->getNumBlockIDs()); // Check if we are entering the EXIT block. if (Blk == &(L.getLocationContext()->getCFG()->getExit())) { assert (L.getLocationContext()->getCFG()->getExit().size() == 0 && "EXIT block cannot contain Stmts."); // Process the final state transition. SubEng.processEndOfFunction(BuilderCtx); // This path is done. Don't enqueue any more nodes. return; } // Call into the SubEngine to process entering the CFGBlock. ExplodedNodeSet dstNodes; BlockEntrance BE(Blk, Pred->getLocationContext()); NodeBuilderWithSinks nodeBuilder(Pred, dstNodes, BuilderCtx, BE); SubEng.processCFGBlockEntrance(L, nodeBuilder); // Auto-generate a node. if (!nodeBuilder.hasGeneratedNodes()) { nodeBuilder.generateNode(Pred->State, Pred); } // Enqueue nodes onto the worklist. enqueue(dstNodes); }
void GRCoreEngine::HandleBlockEdge(const BlockEdge& L, ExplodedNode* Pred) { CFGBlock* Blk = L.getDst(); // Check if we are entering the EXIT block. if (Blk == &(L.getLocationContext()->getCFG()->getExit())) { assert (L.getLocationContext()->getCFG()->getExit().size() == 0 && "EXIT block cannot contain Stmts."); // Process the final state transition. GREndPathNodeBuilder Builder(Blk, Pred, this); ProcessEndPath(Builder); // This path is done. Don't enqueue any more nodes. return; } // FIXME: Should we allow ProcessBlockEntrance to also manipulate state? if (ProcessBlockEntrance(Blk, Pred->State, WList->getBlockCounter())) GenerateNode(BlockEntrance(Blk, Pred->getLocationContext()), Pred->State, Pred); }