diff --git a/clang/lib/Checker/UnreachableCodeChecker.cpp b/clang/lib/Checker/UnreachableCodeChecker.cpp index 432967e00c2b..fd98a7a75d2b 100644 --- a/clang/lib/Checker/UnreachableCodeChecker.cpp +++ b/clang/lib/Checker/UnreachableCodeChecker.cpp @@ -41,6 +41,7 @@ private: static inline const Stmt *getUnreachableStmt(const CFGBlock *CB); void FindUnreachableEntryPoints(const CFGBlock *CB); static bool isInvalidPath(const CFGBlock *CB, const ParentMap &PM); + static inline bool isEmptyCFGBlock(const CFGBlock *CB); llvm::SmallSet reachable; llvm::SmallSet visited; @@ -66,8 +67,8 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G, CFG *C = 0; ParentMap *PM = 0; // Iterate over ExplodedGraph - for (ExplodedGraph::node_iterator I = G.nodes_begin(); I != G.nodes_end(); - ++I) { + for (ExplodedGraph::node_iterator I = G.nodes_begin(), E = G.nodes_end(); + I != E; ++I) { const ProgramPoint &P = I->getLocation(); const LocationContext *LC = P.getLocationContext(); @@ -96,6 +97,10 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G, 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 FindUnreachableEntryPoints(CB); @@ -194,7 +199,12 @@ bool UnreachableCodeChecker::isInvalidPath(const CFGBlock *CB, // Get the predecessor block's terminator conditon const Stmt *cond = pred->getTerminatorCondition(); - assert(cond && "CFGBlock's predecessor has a terminator condition"); + + //assert(cond && "CFGBlock's predecessor has a terminator condition"); + // The previous assertion is invalid in some cases (eg do/while). Leaving + // reporting of these situations on at the moment to help triage these cases. + if (!cond) + return false; // Run each of the checks on the conditions if (containsMacro(cond) || containsEnum(cond) @@ -204,3 +214,10 @@ bool UnreachableCodeChecker::isInvalidPath(const CFGBlock *CB, return false; } + +// Returns true if the given CFGBlock is empty +bool UnreachableCodeChecker::isEmptyCFGBlock(const CFGBlock *CB) { + return CB->getLabel() == 0 // No labels + && CB->size() == 0 // No statements + && CB->getTerminator() == 0; // No terminator +}