29class AnalysisOrderChecker
31 check::PreStmt<CastExpr>, check::PostStmt<CastExpr>,
32 check::PreStmt<ArraySubscriptExpr>,
33 check::PostStmt<ArraySubscriptExpr>, check::PreStmt<CXXNewExpr>,
34 check::PostStmt<CXXNewExpr>, check::PreStmt<CXXDeleteExpr>,
35 check::PostStmt<CXXDeleteExpr>, check::PreStmt<CXXConstructExpr>,
36 check::PostStmt<CXXConstructExpr>, check::PreStmt<OffsetOfExpr>,
37 check::PostStmt<OffsetOfExpr>, check::PreCall, check::PostCall,
38 check::EndFunction, check::EndAnalysis, check::NewAllocator,
39 check::Bind, check::PointerEscape, check::RegionChanges,
40 check::LiveSymbols, eval::Call> {
42 bool isCallbackEnabled(
const AnalyzerOptions &Opts,
43 StringRef CallbackName)
const {
44 return Opts.getCheckerBooleanOption(
this,
"*") ||
45 Opts.getCheckerBooleanOption(
this, CallbackName);
48 bool isCallbackEnabled(CheckerContext &
C, StringRef CallbackName)
const {
49 AnalyzerOptions &Opts =
C.getAnalysisManager().getAnalyzerOptions();
50 return isCallbackEnabled(Opts, CallbackName);
53 bool isCallbackEnabled(
ProgramStateRef State, StringRef CallbackName)
const {
54 AnalyzerOptions &Opts = State->getStateManager().getOwningEngine()
55 .getAnalysisManager().getAnalyzerOptions();
56 return isCallbackEnabled(Opts, CallbackName);
60 void checkPreStmt(
const CastExpr *CE, CheckerContext &
C)
const {
61 if (isCallbackEnabled(
C,
"PreStmtCastExpr"))
66 void checkPostStmt(
const CastExpr *CE, CheckerContext &
C)
const {
67 if (isCallbackEnabled(
C,
"PostStmtCastExpr"))
72 void checkPreStmt(
const ArraySubscriptExpr *SubExpr,
73 CheckerContext &
C)
const {
74 if (isCallbackEnabled(
C,
"PreStmtArraySubscriptExpr"))
75 llvm::errs() <<
"PreStmt<ArraySubscriptExpr>\n";
78 void checkPostStmt(
const ArraySubscriptExpr *SubExpr,
79 CheckerContext &
C)
const {
80 if (isCallbackEnabled(
C,
"PostStmtArraySubscriptExpr"))
81 llvm::errs() <<
"PostStmt<ArraySubscriptExpr>\n";
84 void checkPreStmt(
const CXXNewExpr *NE, CheckerContext &
C)
const {
85 if (isCallbackEnabled(
C,
"PreStmtCXXNewExpr"))
86 llvm::errs() <<
"PreStmt<CXXNewExpr>\n";
89 void checkPostStmt(
const CXXNewExpr *NE, CheckerContext &
C)
const {
90 if (isCallbackEnabled(
C,
"PostStmtCXXNewExpr"))
91 llvm::errs() <<
"PostStmt<CXXNewExpr>\n";
94 void checkPreStmt(
const CXXDeleteExpr *NE, CheckerContext &
C)
const {
95 if (isCallbackEnabled(
C,
"PreStmtCXXDeleteExpr"))
96 llvm::errs() <<
"PreStmt<CXXDeleteExpr>\n";
99 void checkPostStmt(
const CXXDeleteExpr *NE, CheckerContext &
C)
const {
100 if (isCallbackEnabled(
C,
"PostStmtCXXDeleteExpr"))
101 llvm::errs() <<
"PostStmt<CXXDeleteExpr>\n";
104 void checkPreStmt(
const CXXConstructExpr *NE, CheckerContext &
C)
const {
105 if (isCallbackEnabled(
C,
"PreStmtCXXConstructExpr"))
106 llvm::errs() <<
"PreStmt<CXXConstructExpr>\n";
109 void checkPostStmt(
const CXXConstructExpr *NE, CheckerContext &
C)
const {
110 if (isCallbackEnabled(
C,
"PostStmtCXXConstructExpr"))
111 llvm::errs() <<
"PostStmt<CXXConstructExpr>\n";
114 void checkPreStmt(
const OffsetOfExpr *OOE, CheckerContext &
C)
const {
115 if (isCallbackEnabled(
C,
"PreStmtOffsetOfExpr"))
116 llvm::errs() <<
"PreStmt<OffsetOfExpr>\n";
119 void checkPostStmt(
const OffsetOfExpr *OOE, CheckerContext &
C)
const {
120 if (isCallbackEnabled(
C,
"PostStmtOffsetOfExpr"))
121 llvm::errs() <<
"PostStmt<OffsetOfExpr>\n";
124 bool evalCall(
const CallEvent &
Call, CheckerContext &
C)
const {
125 if (isCallbackEnabled(
C,
"EvalCall")) {
126 llvm::errs() <<
"EvalCall";
127 if (
const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(
Call.getDecl()))
128 llvm::errs() <<
" (" << ND->getQualifiedNameAsString() <<
')';
129 llvm::errs() <<
" {argno: " <<
Call.getNumArgs() <<
'}';
130 llvm::errs() <<
" [" <<
Call.getKindAsString() <<
']';
131 llvm::errs() <<
'\n';
137 void checkPreCall(
const CallEvent &
Call, CheckerContext &
C)
const {
138 if (isCallbackEnabled(
C,
"PreCall")) {
139 llvm::errs() <<
"PreCall";
140 if (
const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(
Call.getDecl()))
141 llvm::errs() <<
" (" << ND->getQualifiedNameAsString() <<
')';
142 llvm::errs() <<
" [" <<
Call.getKindAsString() <<
']';
143 llvm::errs() <<
'\n';
147 void checkPostCall(
const CallEvent &
Call, CheckerContext &
C)
const {
148 if (isCallbackEnabled(
C,
"PostCall")) {
149 llvm::errs() <<
"PostCall";
150 if (
const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(
Call.getDecl()))
151 llvm::errs() <<
" (" << ND->getQualifiedNameAsString() <<
')';
152 llvm::errs() <<
" [" <<
Call.getKindAsString() <<
']';
153 llvm::errs() <<
'\n';
157 void checkEndFunction(
const ReturnStmt *S, CheckerContext &
C)
const {
158 if (isCallbackEnabled(
C,
"EndFunction")) {
159 llvm::errs() <<
"EndFunction\nReturnStmt: " << (S ?
"yes" :
"no") <<
"\n";
163 llvm::errs() <<
"CFGElement: ";
164 CFGStmtMap *Map =
C.getCurrentAnalysisDeclContext()->getCFGStmtMap();
167 if (LastElement.
getAs<CFGStmt>())
168 llvm::errs() <<
"CFGStmt\n";
169 else if (LastElement.
getAs<CFGAutomaticObjDtor>())
170 llvm::errs() <<
"CFGAutomaticObjDtor\n";
174 void checkEndAnalysis(ExplodedGraph &G, BugReporter &BR,
175 ExprEngine &Eng)
const {
177 llvm::errs() <<
"EndAnalysis\n";
180 void checkNewAllocator(
const CXXAllocatorCall &
Call,
181 CheckerContext &
C)
const {
182 if (isCallbackEnabled(
C,
"NewAllocator"))
183 llvm::errs() <<
"NewAllocator\n";
186 void checkBind(SVal Loc, SVal Val,
const Stmt *S,
bool AtDeclInit,
187 CheckerContext &
C)
const {
188 if (isCallbackEnabled(
C,
"Bind"))
189 llvm::errs() <<
"Bind\n";
192 void checkLiveSymbols(
ProgramStateRef State, SymbolReaper &SymReaper)
const {
193 if (isCallbackEnabled(State,
"LiveSymbols"))
194 llvm::errs() <<
"LiveSymbols\n";
200 ArrayRef<const MemRegion *> ExplicitRegions,
201 ArrayRef<const MemRegion *> Regions,
202 const LocationContext *LCtx,
const CallEvent *
Call)
const {
203 if (isCallbackEnabled(State,
"RegionChanges"))
204 llvm::errs() <<
"RegionChanges\n";
210 const CallEvent *
Call,
212 if (isCallbackEnabled(State,
"PointerEscape"))
213 llvm::errs() <<
"PointerEscape\n";
227bool ento::shouldRegisterAnalysisOrderChecker(
const CheckerManager &mgr) {
Defines the clang::Expr interface and subclasses for C++ expressions.
std::optional< T > getAs() const
Convert to the specified CFGElement type, returning std::nullopt if this CFGElement is not of the des...
CFGBlock * getBlock(Stmt *S)
Returns the CFGBlock the specified Stmt* appears in.
static const char * getCastKindName(CastKind CK)
const AnalyzerOptions & getAnalyzerOptions()
CHECKER * registerChecker(AT &&...Args)
Register a single-part checker (derived from Checker): construct its singleton instance,...
Simple checker classes that implement one frontend (i.e.
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
llvm::DenseSet< SymbolRef > InvalidatedSymbols
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The JSON file list parser is used to communicate input to InstallAPI.