1 //===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Defines the Static Analyzer Checker Manager.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
15 #define LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
17 #include "clang/Analysis/ProgramPoint.h"
18 #include "clang/Basic/LangOptions.h"
19 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
20 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/SmallVector.h"
32 class CheckerRegistry;
34 class AnalysisManager;
40 class ExplodedNodeSet;
44 struct NodeBuilderContext;
48 template <typename T> class CheckerFn;
50 template <typename RET, typename... Ps>
51 class CheckerFn<RET(Ps...)> {
52 typedef RET (*Func)(void *, Ps...);
56 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
57 RET operator()(Ps... ps) const {
58 return Fn(Checker, ps...);
62 /// \brief Describes the different reasons a pointer escapes
64 enum PointerEscapeKind {
65 /// A pointer escapes due to binding its value to a location
66 /// that the analyzer cannot track.
69 /// The pointer has been passed to a function call directly.
70 PSK_DirectEscapeOnCall,
72 /// The pointer has been passed to a function indirectly.
73 /// For example, the pointer is accessible through an
74 /// argument to a function.
75 PSK_IndirectEscapeOnCall,
77 /// The reason for pointer escape is unknown. For example,
78 /// a region containing this pointer is invalidated.
82 // This wrapper is used to ensure that only StringRefs originating from the
83 // CheckerRegistry are used as check names. We want to make sure all check
84 // name strings have a lifetime that keeps them alive at least until the path
85 // diagnostics have been processed.
88 friend class ::clang::ento::CheckerRegistry;
89 explicit CheckName(StringRef Name) : Name(Name) {}
93 CheckName(const CheckName &Other) : Name(Other.Name) {}
94 StringRef getName() const { return Name; }
97 class CheckerManager {
98 const LangOptions LangOpts;
99 AnalyzerOptionsRef AOptions;
100 CheckName CurrentCheckName;
103 CheckerManager(const LangOptions &langOpts,
104 AnalyzerOptionsRef AOptions)
105 : LangOpts(langOpts),
106 AOptions(AOptions) {}
110 void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
111 CheckName getCurrentCheckName() const { return CurrentCheckName; }
113 bool hasPathSensitiveCheckers() const;
115 void finishedCheckerRegistration();
117 const LangOptions &getLangOpts() const { return LangOpts; }
118 AnalyzerOptions &getAnalyzerOptions() { return *AOptions; }
120 typedef CheckerBase *CheckerRef;
121 typedef const void *CheckerTag;
122 typedef CheckerFn<void ()> CheckerDtor;
124 //===----------------------------------------------------------------------===//
126 //===----------------------------------------------------------------------===//
128 /// \brief Used to register checkers.
130 /// \returns a pointer to the checker object.
131 template <typename CHECKER>
132 CHECKER *registerChecker() {
133 CheckerTag tag = getTag<CHECKER>();
134 CheckerRef &ref = CheckerTags[tag];
136 return static_cast<CHECKER *>(ref); // already registered.
138 CHECKER *checker = new CHECKER();
139 checker->Name = CurrentCheckName;
140 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
141 CHECKER::_register(checker, *this);
146 template <typename CHECKER>
147 CHECKER *registerChecker(AnalyzerOptions &AOpts) {
148 CheckerTag tag = getTag<CHECKER>();
149 CheckerRef &ref = CheckerTags[tag];
151 return static_cast<CHECKER *>(ref); // already registered.
153 CHECKER *checker = new CHECKER(AOpts);
154 checker->Name = CurrentCheckName;
155 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
156 CHECKER::_register(checker, *this);
161 //===----------------------------------------------------------------------===//
162 // Functions for running checkers for AST traversing..
163 //===----------------------------------------------------------------------===//
165 /// \brief Run checkers handling Decls.
166 void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
169 /// \brief Run checkers handling Decls containing a Stmt body.
170 void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
173 //===----------------------------------------------------------------------===//
174 // Functions for running checkers for path-sensitive checking.
175 //===----------------------------------------------------------------------===//
177 /// \brief Run checkers for pre-visiting Stmts.
179 /// The notification is performed for every explored CFGElement, which does
180 /// not include the control flow statements such as IfStmt.
182 /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
183 void runCheckersForPreStmt(ExplodedNodeSet &Dst,
184 const ExplodedNodeSet &Src,
187 runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
190 /// \brief Run checkers for post-visiting Stmts.
192 /// The notification is performed for every explored CFGElement, which does
193 /// not include the control flow statements such as IfStmt.
195 /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
196 void runCheckersForPostStmt(ExplodedNodeSet &Dst,
197 const ExplodedNodeSet &Src,
200 bool wasInlined = false) {
201 runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
204 /// \brief Run checkers for visiting Stmts.
205 void runCheckersForStmt(bool isPreVisit,
206 ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
207 const Stmt *S, ExprEngine &Eng,
208 bool wasInlined = false);
210 /// \brief Run checkers for pre-visiting obj-c messages.
211 void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
212 const ExplodedNodeSet &Src,
213 const ObjCMethodCall &msg,
215 runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
218 /// \brief Run checkers for post-visiting obj-c messages.
219 void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
220 const ExplodedNodeSet &Src,
221 const ObjCMethodCall &msg,
223 bool wasInlined = false) {
224 runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng,
228 /// \brief Run checkers for visiting obj-c messages.
229 void runCheckersForObjCMessage(bool isPreVisit,
230 ExplodedNodeSet &Dst,
231 const ExplodedNodeSet &Src,
232 const ObjCMethodCall &msg, ExprEngine &Eng,
233 bool wasInlined = false);
235 /// \brief Run checkers for pre-visiting obj-c messages.
236 void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
237 const CallEvent &Call, ExprEngine &Eng) {
238 runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
241 /// \brief Run checkers for post-visiting obj-c messages.
242 void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
243 const CallEvent &Call, ExprEngine &Eng,
244 bool wasInlined = false) {
245 runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
249 /// \brief Run checkers for visiting obj-c messages.
250 void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
251 const ExplodedNodeSet &Src,
252 const CallEvent &Call, ExprEngine &Eng,
253 bool wasInlined = false);
255 /// \brief Run checkers for load/store of a location.
256 void runCheckersForLocation(ExplodedNodeSet &Dst,
257 const ExplodedNodeSet &Src,
264 /// \brief Run checkers for binding of a value to a location.
265 void runCheckersForBind(ExplodedNodeSet &Dst,
266 const ExplodedNodeSet &Src,
267 SVal location, SVal val,
268 const Stmt *S, ExprEngine &Eng,
269 const ProgramPoint &PP);
271 /// \brief Run checkers for end of analysis.
272 void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
275 /// \brief Run checkers on end of function.
276 void runCheckersForEndFunction(NodeBuilderContext &BC,
277 ExplodedNodeSet &Dst,
281 /// \brief Run checkers for branch condition.
282 void runCheckersForBranchCondition(const Stmt *condition,
283 ExplodedNodeSet &Dst, ExplodedNode *Pred,
286 /// \brief Run checkers for live symbols.
288 /// Allows modifying SymbolReaper object. For example, checkers can explicitly
289 /// register symbols of interest as live. These symbols will not be marked
290 /// dead and removed.
291 void runCheckersForLiveSymbols(ProgramStateRef state,
292 SymbolReaper &SymReaper);
294 /// \brief Run checkers for dead symbols.
296 /// Notifies checkers when symbols become dead. For example, this allows
297 /// checkers to aggressively clean up/reduce the checker state and produce
298 /// precise diagnostics.
299 void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
300 const ExplodedNodeSet &Src,
301 SymbolReaper &SymReaper, const Stmt *S,
303 ProgramPoint::Kind K);
305 /// \brief True if at least one checker wants to check region changes.
306 bool wantsRegionChangeUpdate(ProgramStateRef state);
308 /// \brief Run checkers for region changes.
310 /// This corresponds to the check::RegionChanges callback.
311 /// \param state The current program state.
312 /// \param invalidated A set of all symbols potentially touched by the change.
313 /// \param ExplicitRegions The regions explicitly requested for invalidation.
314 /// For example, in the case of a function call, these would be arguments.
315 /// \param Regions The transitive closure of accessible regions,
316 /// i.e. all regions that may have been touched by this change.
317 /// \param Call The call expression wrapper if the regions are invalidated
320 runCheckersForRegionChanges(ProgramStateRef state,
321 const InvalidatedSymbols *invalidated,
322 ArrayRef<const MemRegion *> ExplicitRegions,
323 ArrayRef<const MemRegion *> Regions,
324 const CallEvent *Call);
326 /// \brief Run checkers when pointers escape.
328 /// This notifies the checkers about pointer escape, which occurs whenever
329 /// the analyzer cannot track the symbol any more. For example, as a
330 /// result of assigning a pointer into a global or when it's passed to a
331 /// function call the analyzer cannot model.
333 /// \param State The state at the point of escape.
334 /// \param Escaped The list of escaped symbols.
335 /// \param Call The corresponding CallEvent, if the symbols escape as
336 /// parameters to the given call.
337 /// \param Kind The reason of pointer escape.
338 /// \param ITraits Information about invalidation for a particular
340 /// \returns Checkers can modify the state by returning a new one.
342 runCheckersForPointerEscape(ProgramStateRef State,
343 const InvalidatedSymbols &Escaped,
344 const CallEvent *Call,
345 PointerEscapeKind Kind,
346 RegionAndSymbolInvalidationTraits *ITraits);
348 /// \brief Run checkers for handling assumptions on symbolic values.
349 ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
350 SVal Cond, bool Assumption);
352 /// \brief Run checkers for evaluating a call.
354 /// Warning: Currently, the CallEvent MUST come from a CallExpr!
355 void runCheckersForEvalCall(ExplodedNodeSet &Dst,
356 const ExplodedNodeSet &Src,
357 const CallEvent &CE, ExprEngine &Eng);
359 /// \brief Run checkers for the entire Translation Unit.
360 void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
361 AnalysisManager &mgr,
364 /// \brief Run checkers for debug-printing a ProgramState.
366 /// Unlike most other callbacks, any checker can simply implement the virtual
367 /// method CheckerBase::printState if it has custom data to print.
368 /// \param Out The output stream
369 /// \param State The state being printed
370 /// \param NL The preferred representation of a newline.
371 /// \param Sep The preferred separator between different kinds of data.
372 void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
373 const char *NL, const char *Sep);
375 //===----------------------------------------------------------------------===//
376 // Internal registration functions for AST traversing.
377 //===----------------------------------------------------------------------===//
379 // Functions used by the registration mechanism, checkers should not touch
382 typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
385 typedef bool (*HandlesDeclFunc)(const Decl *D);
386 void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
388 void _registerForBody(CheckDeclFunc checkfn);
390 //===----------------------------------------------------------------------===//
391 // Internal registration functions for path-sensitive checking.
392 //===----------------------------------------------------------------------===//
394 typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
396 typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
397 CheckObjCMessageFunc;
399 typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
402 typedef CheckerFn<void (const SVal &location, bool isLoad,
407 typedef CheckerFn<void (const SVal &location, const SVal &val,
408 const Stmt *S, CheckerContext &)>
411 typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
412 CheckEndAnalysisFunc;
414 typedef CheckerFn<void (CheckerContext &)>
415 CheckEndFunctionFunc;
417 typedef CheckerFn<void (const Stmt *, CheckerContext &)>
418 CheckBranchConditionFunc;
420 typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
421 CheckDeadSymbolsFunc;
423 typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
425 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
426 const InvalidatedSymbols *symbols,
427 ArrayRef<const MemRegion *> ExplicitRegions,
428 ArrayRef<const MemRegion *> Regions,
429 const CallEvent *Call)>
430 CheckRegionChangesFunc;
432 typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
434 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
435 const InvalidatedSymbols &Escaped,
436 const CallEvent *Call,
437 PointerEscapeKind Kind,
438 RegionAndSymbolInvalidationTraits *ITraits)>
439 CheckPointerEscapeFunc;
441 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
442 const SVal &cond, bool assumption)>
445 typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
448 typedef CheckerFn<void (const TranslationUnitDecl *,
449 AnalysisManager&, BugReporter &)>
450 CheckEndOfTranslationUnit;
452 typedef bool (*HandlesStmtFunc)(const Stmt *D);
453 void _registerForPreStmt(CheckStmtFunc checkfn,
454 HandlesStmtFunc isForStmtFn);
455 void _registerForPostStmt(CheckStmtFunc checkfn,
456 HandlesStmtFunc isForStmtFn);
458 void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
459 void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
461 void _registerForPreCall(CheckCallFunc checkfn);
462 void _registerForPostCall(CheckCallFunc checkfn);
464 void _registerForLocation(CheckLocationFunc checkfn);
466 void _registerForBind(CheckBindFunc checkfn);
468 void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
470 void _registerForEndFunction(CheckEndFunctionFunc checkfn);
472 void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
474 void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
476 void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
478 void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
479 WantsRegionChangeUpdateFunc wantUpdateFn);
481 void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
483 void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
485 void _registerForEvalAssume(EvalAssumeFunc checkfn);
487 void _registerForEvalCall(EvalCallFunc checkfn);
489 void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
491 //===----------------------------------------------------------------------===//
492 // Internal registration functions for events.
493 //===----------------------------------------------------------------------===//
495 typedef void *EventTag;
496 typedef CheckerFn<void (const void *event)> CheckEventFunc;
498 template <typename EVENT>
499 void _registerListenerForEvent(CheckEventFunc checkfn) {
500 EventInfo &info = Events[getTag<EVENT>()];
501 info.Checkers.push_back(checkfn);
504 template <typename EVENT>
505 void _registerDispatcherForEvent() {
506 EventInfo &info = Events[getTag<EVENT>()];
507 info.HasDispatcher = true;
510 template <typename EVENT>
511 void _dispatchEvent(const EVENT &event) const {
512 EventsTy::const_iterator I = Events.find(getTag<EVENT>());
513 if (I == Events.end())
515 const EventInfo &info = I->second;
516 for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
517 info.Checkers[i](&event);
520 //===----------------------------------------------------------------------===//
521 // Implementation details.
522 //===----------------------------------------------------------------------===//
525 template <typename CHECKER>
526 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
528 template <typename T>
529 static void *getTag() { static int tag; return &tag; }
531 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
533 std::vector<CheckerDtor> CheckerDtors;
535 struct DeclCheckerInfo {
536 CheckDeclFunc CheckFn;
537 HandlesDeclFunc IsForDeclFn;
539 std::vector<DeclCheckerInfo> DeclCheckers;
541 std::vector<CheckDeclFunc> BodyCheckers;
543 typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
544 typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
545 CachedDeclCheckersMapTy CachedDeclCheckersMap;
547 struct StmtCheckerInfo {
548 CheckStmtFunc CheckFn;
549 HandlesStmtFunc IsForStmtFn;
552 std::vector<StmtCheckerInfo> StmtCheckers;
554 typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
555 typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
556 CachedStmtCheckersMapTy CachedStmtCheckersMap;
558 const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
561 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
562 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
564 std::vector<CheckCallFunc> PreCallCheckers;
565 std::vector<CheckCallFunc> PostCallCheckers;
567 std::vector<CheckLocationFunc> LocationCheckers;
569 std::vector<CheckBindFunc> BindCheckers;
571 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
573 std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
575 std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
577 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
579 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
581 struct RegionChangesCheckerInfo {
582 CheckRegionChangesFunc CheckFn;
583 WantsRegionChangeUpdateFunc WantUpdateFn;
585 std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
587 std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
589 std::vector<EvalAssumeFunc> EvalAssumeCheckers;
591 std::vector<EvalCallFunc> EvalCallCheckers;
593 std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
596 SmallVector<CheckEventFunc, 4> Checkers;
598 EventInfo() : HasDispatcher(false) { }
601 typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
605 } // end ento namespace
607 } // end clang namespace