27 #include "llvm/ADT/SmallSet.h"
29 using namespace clang;
33 class UnreachableCodeChecker :
public Checker<check::EndAnalysis> {
38 typedef llvm::SmallSet<unsigned, 32> CFGBlocksSet;
40 static inline const Stmt *getUnreachableStmt(
const CFGBlock *CB);
41 static void FindUnreachableEntryPoints(
const CFGBlock *CB,
42 CFGBlocksSet &reachable,
43 CFGBlocksSet &visited);
45 static inline bool isEmptyCFGBlock(
const CFGBlock *CB);
49 void UnreachableCodeChecker::checkEndAnalysis(
ExplodedGraph &G,
52 CFGBlocksSet reachable, visited;
57 const Decl *D =
nullptr;
92 if (FD->isTemplateInstantiation())
103 if (isEmptyCFGBlock(CB))
108 FindUnreachableEntryPoints(CB, reachable, visited);
115 if (CB->
size() > 0 && isInvalidPath(CB, *PM))
123 if (label->getStmtClass() == Stmt::DefaultStmtClass)
130 bool foundUnreachable =
false;
134 if (
const CallExpr *CE = dyn_cast<CallExpr>(
S->getStmt())) {
135 if (CE->getBuiltinCallee() == Builtin::BI__builtin_unreachable) {
136 foundUnreachable =
true;
141 if (foundUnreachable)
149 if (
const Stmt *
S = getUnreachableStmt(CB)) {
150 SR =
S->getSourceRange();
165 "This statement is never executed", DL, SR);
170 void UnreachableCodeChecker::FindUnreachableEntryPoints(
const CFGBlock *CB,
171 CFGBlocksSet &reachable,
172 CFGBlocksSet &visited) {
180 if (!reachable.count((*I)->getBlockID())) {
184 if (!visited.count((*I)->getBlockID()))
186 FindUnreachableEntryPoints(*
I, reachable, visited);
192 const Stmt *UnreachableCodeChecker::getUnreachableStmt(
const CFGBlock *CB) {
208 bool UnreachableCodeChecker::isInvalidPath(
const CFGBlock *CB,
236 containsStmt<UnaryExprOrTypeTraitExpr>(cond);
240 bool UnreachableCodeChecker::isEmptyCFGBlock(
const CFGBlock *CB) {
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
bool containsStaticLocal(const Stmt *S)
Defines the SourceManager interface.
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
bool containsBuiltinOffsetOf(const Stmt *S)
FullSourceLoc asLocation() const
AnalysisDeclContext * getAnalysisDeclContext() const
unsigned pred_size() const
ElementList::const_iterator const_iterator
const Decl * getDecl() const
detail::InMemoryDirectory::const_iterator I
CFGBlock - Represents a single basic block in a source-level CFG.
Stmt * getTerminatorCondition(bool StripParens=true)
CFG - Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
ParentMap & getParentMap() const
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
AdjacentBlocks::const_iterator const_pred_iterator
unsigned getBlockID() const
bool hasWorkRemaining() const
CFG * getUnoptimizedCFG()
Return a version of the CFG without any edges pruned.
BugReporter is a utility class for generating PathDiagnostics for analysis.
CFGTerminator getTerminator()
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
CHECKER * registerChecker()
Used to register checkers.
node_iterator nodes_begin()
Encodes a location in the source.
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges=None)
node_iterator nodes_end()
pred_iterator pred_begin()
const LocationContext * getLocationContext() const
detail::InMemoryDirectory::const_iterator E
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
SourceManager & getSourceManager()
bool containsMacro(const Stmt *S)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
AllNodesTy::iterator node_iterator
bool isInExternCSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in an "extern C" system header.
A trivial tuple used to represent a source range.
bool containsEnum(const Stmt *S)
This class handles loading and caching of source files into memory.
Defines enum values for all the target-independent builtin functions.