26#include "llvm/ADT/SmallSet.h"
33class 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);
49void UnreachableCodeChecker::checkEndAnalysis(
ExplodedGraph &G,
52 CFGBlocksSet reachable, visited;
57 const Decl *
D =
nullptr;
64 LC =
P.getLocationContext();
91 if (FD->isTemplateInstantiation())
101 if (isEmptyCFGBlock(CB))
106 FindUnreachableEntryPoints(CB, reachable, visited);
113 if (isInvalidPath(CB, *PM))
121 if (label->getStmtClass() == Stmt::DefaultStmtClass)
128 bool foundUnreachable =
false;
131 if (std::optional<CFGStmt> S = (*ci).getAs<
CFGStmt>())
132 if (
const CallExpr *CE = dyn_cast<CallExpr>(S->getStmt())) {
133 if (CE->getBuiltinCallee() == Builtin::BI__builtin_unreachable ||
135 foundUnreachable =
true;
140 if (foundUnreachable)
148 if (
const Stmt *S = getUnreachableStmt(CB)) {
151 if (S->getBeginLoc().isMacroID())
152 if (
const auto *I = dyn_cast<IntegerLiteral>(S))
153 if (I->getValue() == 0ULL)
157 SR = S->getSourceRange();
162 if (isa<CXXTryStmt>(S))
170 if (
SM.isInSystemHeader(SL) ||
SM.isInExternCSystemHeader(SL))
174 "This statement is never executed", DL, SR);
179void UnreachableCodeChecker::FindUnreachableEntryPoints(
const CFGBlock *CB,
180 CFGBlocksSet &reachable,
181 CFGBlocksSet &visited) {
188 if (!reachable.count(PredBlock->getBlockID())) {
192 if (!visited.count(PredBlock->getBlockID()))
194 FindUnreachableEntryPoints(PredBlock, reachable, visited);
200const Stmt *UnreachableCodeChecker::getUnreachableStmt(
const CFGBlock *CB) {
202 if (std::optional<CFGStmt> S = Elem.getAs<
CFGStmt>()) {
203 if (!isa<DeclStmt>(S->getStmt()))
207 return CB->getTerminatorStmt();
215bool UnreachableCodeChecker::isInvalidPath(
const CFGBlock *CB,
243 containsStmt<UnaryExprOrTypeTraitExpr>(cond);
247bool UnreachableCodeChecker::isEmptyCFGBlock(
const CFGBlock *CB) {
257bool ento::shouldRegisterUnreachableCodeChecker(
const CheckerManager &mgr) {
Defines enum values for all the target-independent builtin functions.
Defines the SourceManager interface.
const Decl * getDecl() const
CFG * getUnoptimizedCFG()
Represents a single basic block in a source-level CFG.
ElementList::const_iterator const_iterator
Stmt * getTerminatorStmt()
unsigned pred_size() const
pred_iterator pred_begin()
unsigned getBlockID() const
Stmt * getTerminatorCondition(bool StripParens=true)
Represents a top-level expression in a basic block.
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Decl - This represents one declaration (or definition), e.g.
Represents a function declaration or definition.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const ParentMap & getParentMap() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
virtual bool inTopFrame() const
Stmt * getParent(Stmt *) const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
BugReporter is a utility class for generating PathDiagnostics for analysis.
const SourceManager & getSourceManager()
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges=std::nullopt, ArrayRef< FixItHint > Fixits=std::nullopt)
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
llvm::iterator_range< node_iterator > nodes()
bool hasWorkRemaining() const
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
FullSourceLoc asLocation() const
const char *const UnusedCode
bool containsEnum(const Stmt *S)
bool containsStaticLocal(const Stmt *S)
bool containsBuiltinOffsetOf(const Stmt *S)
bool containsMacro(const Stmt *S)
The JSON file list parser is used to communicate input to InstallAPI.