/// Add each synthetic statement in the CFG to the parent map, using the /// source statement's parent. static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) { if (!TheCFG) return; for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(), E = TheCFG->synthetic_stmt_end(); I != E; ++I) { PM.setParent(I->first, PM.getParent(I->second)); } }
void setLevelMapFromMST( const Graph& mst , LevelMap& lm , ParentMap& parents , typename Graph::vertex_descriptor root ) { const typename Graph::boost_graph& mst_bg = mst.boostGraph(); lm.clear(); lm.resize( num_vertices(mst_bg) ); parents.clear(); parents.resize( num_vertices(mst_bg) ); lm[root] = 0; // Source or root Node parents[root] = -1; // Root has no parent breadth_first_search( mst_bg , root , boost::visitor(record_levels(lm,parents))); }
static SourceLocation getValidSourceLocation(const Stmt* S, LocationOrAnalysisContext LAC) { SourceLocation L = S->getLocStart(); assert(!LAC.isNull() && "A valid LocationContext or AnalysisContext should " "be passed to PathDiagnosticLocation upon creation."); // S might be a temporary statement that does not have a location in the // source code, so find an enclosing statement and use it's location. if (!L.isValid()) { ParentMap *PM = 0; if (LAC.is<const LocationContext*>()) PM = &LAC.get<const LocationContext*>()->getParentMap(); else PM = &LAC.get<AnalysisContext*>()->getParentMap(); while (!L.isValid()) { S = PM->getParent(S); L = S->getLocStart(); } } return L; }
void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G, BugReporter &B, ExprEngine &Eng) const { CFGBlocksSet reachable, visited; if (Eng.hasWorkRemaining()) return; const Decl *D = nullptr; CFG *C = nullptr; ParentMap *PM = nullptr; const LocationContext *LC = nullptr; // Iterate over ExplodedGraph for (ExplodedGraph::node_iterator I = G.nodes_begin(), E = G.nodes_end(); I != E; ++I) { const ProgramPoint &P = I->getLocation(); LC = P.getLocationContext(); if (!LC->inTopFrame()) continue; if (!D) D = LC->getAnalysisDeclContext()->getDecl(); // Save the CFG if we don't have it already if (!C) C = LC->getAnalysisDeclContext()->getUnoptimizedCFG(); if (!PM) PM = &LC->getParentMap(); if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>()) { const CFGBlock *CB = BE->getBlock(); reachable.insert(CB->getBlockID()); } } // Bail out if we didn't get the CFG or the ParentMap. if (!D || !C || !PM) return; // Don't do anything for template instantiations. Proving that code // in a template instantiation is unreachable means proving that it is // unreachable in all instantiations. if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) if (FD->isTemplateInstantiation()) return; // Find CFGBlocks that were not covered by any node for (CFG::const_iterator I = C->begin(), E = C->end(); I != E; ++I) { const CFGBlock *CB = *I; // Check if the block is unreachable if (reachable.count(CB->getBlockID())) continue; // Check if the block is empty (an artificial block) if (isEmptyCFGBlock(CB)) continue; // Find the entry points for this block if (!visited.count(CB->getBlockID())) FindUnreachableEntryPoints(CB, reachable, visited); // This block may have been pruned; check if we still want to report it if (reachable.count(CB->getBlockID())) continue; // Check for false positives if (isInvalidPath(CB, *PM)) continue; // It is good practice to always have a "default" label in a "switch", even // if we should never get there. It can be used to detect errors, for // instance. Unreachable code directly under a "default" label is therefore // likely to be a false positive. if (const Stmt *label = CB->getLabel()) if (label->getStmtClass() == Stmt::DefaultStmtClass) continue; // Special case for __builtin_unreachable. // FIXME: This should be extended to include other unreachable markers, // such as llvm_unreachable. if (!CB->empty()) { bool foundUnreachable = false; for (CFGBlock::const_iterator ci = CB->begin(), ce = CB->end(); ci != ce; ++ci) { if (Optional<CFGStmt> S = (*ci).getAs<CFGStmt>()) if (const CallExpr *CE = dyn_cast<CallExpr>(S->getStmt())) { if (CE->getBuiltinCallee() == Builtin::BI__builtin_unreachable || CE->isBuiltinAssumeFalse(Eng.getContext())) { foundUnreachable = true; break; } } } if (foundUnreachable) continue; } // We found a block that wasn't covered - find the statement to report SourceRange SR; PathDiagnosticLocation DL; SourceLocation SL; if (const Stmt *S = getUnreachableStmt(CB)) { // In macros, 'do {...} while (0)' is often used. Don't warn about the // condition 0 when it is unreachable. if (S->getBeginLoc().isMacroID()) if (const auto *I = dyn_cast<IntegerLiteral>(S)) if (I->getValue() == 0ULL) if (const Stmt *Parent = PM->getParent(S)) if (isa<DoStmt>(Parent)) continue; SR = S->getSourceRange(); DL = PathDiagnosticLocation::createBegin(S, B.getSourceManager(), LC); SL = DL.asLocation(); if (SR.isInvalid() || !SL.isValid()) continue; } else continue; // Check if the SourceLocation is in a system header const SourceManager &SM = B.getSourceManager(); if (SM.isInSystemHeader(SL) || SM.isInExternCSystemHeader(SL)) continue; B.EmitBasicReport(D, this, "Unreachable code", "Dead code", "This statement is never executed", DL, SR); } }
// 路径搜索算法 void GameGrid::PathFinding(const Point3& start, const Point3& end) { if (start==end) return; typedef map<WorldGrid*, float> CostMap; CostMap total_cost; typedef map<WorldGrid*, WorldGrid*> ParentMap; ParentMap parents; m_OpenList.clear(); m_CloseList.clear(); m_Path.clear(); //float total_cost = 0.0f; WorldGrid* grid = &m_World[start.x][start.y][start.z]; Point3 pos = start; m_OpenList.insert(grid); total_cost[grid] = 0.0f; while(pos != end) { OpenList::iterator iter = m_OpenList.begin(); if (iter != m_OpenList.end()) { grid = *iter; m_OpenList.erase(m_OpenList.begin()); //total_cost } else { break; } m_CloseList.insert(grid); for (unsigned int i=0; i<grid->neighbourCount; i++) { Point3& npos = grid->neighbourPos[i]; // 注: 这里和原文不一样 WorldGrid* neighbour = &m_World[npos.x][npos.y][npos.z]; float cost = total_cost[grid] + neighbour->length[i]; if (m_OpenList.find(neighbour) != m_OpenList.end() && (cost < total_cost[neighbour])) m_OpenList.erase(neighbour); if (m_CloseList.find(neighbour) != m_CloseList.end() && (cost < total_cost[neighbour])) m_CloseList.erase(neighbour); if (m_OpenList.find(neighbour) == m_OpenList.end() && m_CloseList.find(neighbour) == m_CloseList.end()) { total_cost[neighbour] = cost; //neighbour->priority = cost + abs(end.x - npos.x) + abs(end.y - npos.y) + abs(end.z - npos.z); neighbour->priority = cost + sqrt((float)(end - npos).SquaredLength()); m_OpenList.insert(neighbour); parents[neighbour] = grid; } } //sort(m_OpenList.begin(), m_OpenList.end(), WorldGridComparer); OpenList::iterator openIter = m_OpenList.begin(); if (openIter!=m_OpenList.end()) { pos = (*openIter)->pos; if (pos == end) break; } else break; } //Mesh* sphere = MeshManager::Instance().GetByName("sphere"); for (WorldGrid* g=&m_World[pos.x][pos.y][pos.z]; parents.find(g)!=parents.end(); g=parents[g]) { // Test render path //MeshObject* obj = FACTORY_CREATE(m_Scene, MeshObject); //obj->SetPosition(g->obj->WorldTransform().GetPosition() + Vector3f(0.0f, 0.5f, 0.0f)); //obj->SetMesh(sphere); //m_Scene->AddObject(obj); m_Path.push_front(g); } m_TestRun = true; }