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';
138 void checkPreCall(
const CallEvent &
Call, CheckerContext &
C)
const {
139 if (isCallbackEnabled(
C,
"PreCall")) {
140 llvm::errs() <<
"PreCall";
141 if (
const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(
Call.getDecl()))
142 llvm::errs() <<
" (" << ND->getQualifiedNameAsString() <<
')';
143 llvm::errs() <<
" [" <<
Call.getKindAsString() <<
']';
144 llvm::errs() <<
'\n';
148 void checkPostCall(
const CallEvent &
Call, CheckerContext &
C)
const {
149 if (isCallbackEnabled(
C,
"PostCall")) {
150 llvm::errs() <<
"PostCall";
151 if (
const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(
Call.getDecl()))
152 llvm::errs() <<
" (" << ND->getQualifiedNameAsString() <<
')';
153 llvm::errs() <<
" [" <<
Call.getKindAsString() <<
']';
154 llvm::errs() <<
'\n';
158 void checkEndFunction(
const ReturnStmt *S, CheckerContext &
C)
const {
159 if (isCallbackEnabled(
C,
"EndFunction")) {
160 llvm::errs() <<
"EndFunction\nReturnStmt: " << (S ?
"yes" :
"no") <<
"\n";
164 llvm::errs() <<
"CFGElement: ";
165 CFGStmtMap *Map =
C.getCurrentAnalysisDeclContext()->getCFGStmtMap();
168 if (LastElement.
getAs<CFGStmt>())
169 llvm::errs() <<
"CFGStmt\n";
170 else if (LastElement.
getAs<CFGAutomaticObjDtor>())
171 llvm::errs() <<
"CFGAutomaticObjDtor\n";
175 void checkEndAnalysis(ExplodedGraph &G, BugReporter &BR,
176 ExprEngine &Eng)
const {
178 llvm::errs() <<
"EndAnalysis\n";
181 void checkNewAllocator(
const CXXAllocatorCall &
Call,
182 CheckerContext &
C)
const {
183 if (isCallbackEnabled(
C,
"NewAllocator"))
184 llvm::errs() <<
"NewAllocator\n";
187 void checkBind(SVal Loc, SVal Val,
const Stmt *S,
bool AtDeclInit,
188 CheckerContext &
C)
const {
189 if (isCallbackEnabled(
C,
"Bind"))
190 llvm::errs() <<
"Bind\n";
193 void checkLiveSymbols(
ProgramStateRef State, SymbolReaper &SymReaper)
const {
194 if (isCallbackEnabled(State,
"LiveSymbols"))
195 llvm::errs() <<
"LiveSymbols\n";
201 ArrayRef<const MemRegion *> ExplicitRegions,
202 ArrayRef<const MemRegion *> Regions,
203 const LocationContext *LCtx,
const CallEvent *
Call)
const {
204 if (isCallbackEnabled(State,
"RegionChanges"))
205 llvm::errs() <<
"RegionChanges\n";
211 const CallEvent *
Call,
213 if (isCallbackEnabled(State,
"PointerEscape"))
214 llvm::errs() <<
"PointerEscape\n";
228bool 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.