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"
33 class CheckerRegistry;
35 class AnalysisManager;
41 class ExplodedNodeSet;
45 struct NodeBuilderContext;
49 template <typename T> class CheckerFn;
51 template <typename RET, typename... Ps>
52 class CheckerFn<RET(Ps...)> {
53 typedef RET (*Func)(void *, Ps...);
57 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
58 RET operator()(Ps... ps) const {
59 return Fn(Checker, ps...);
63 /// \brief Describes the different reasons a pointer escapes
65 enum PointerEscapeKind {
66 /// A pointer escapes due to binding its value to a location
67 /// that the analyzer cannot track.
70 /// The pointer has been passed to a function call directly.
71 PSK_DirectEscapeOnCall,
73 /// The pointer has been passed to a function indirectly.
74 /// For example, the pointer is accessible through an
75 /// argument to a function.
76 PSK_IndirectEscapeOnCall,
78 /// The reason for pointer escape is unknown. For example,
79 /// a region containing this pointer is invalidated.
83 // This wrapper is used to ensure that only StringRefs originating from the
84 // CheckerRegistry are used as check names. We want to make sure all check
85 // name strings have a lifetime that keeps them alive at least until the path
86 // diagnostics have been processed.
89 friend class ::clang::ento::CheckerRegistry;
90 explicit CheckName(StringRef Name) : Name(Name) {}
93 CheckName() = default;
94 StringRef getName() const { return Name; }
97 enum class ObjCMessageVisitKind {
103 class CheckerManager {
104 const LangOptions LangOpts;
105 AnalyzerOptions &AOptions;
106 CheckName CurrentCheckName;
109 CheckerManager(const LangOptions &langOpts, AnalyzerOptions &AOptions)
110 : LangOpts(langOpts), AOptions(AOptions) {}
114 void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
115 CheckName getCurrentCheckName() const { return CurrentCheckName; }
117 bool hasPathSensitiveCheckers() const;
119 void finishedCheckerRegistration();
121 const LangOptions &getLangOpts() const { return LangOpts; }
122 AnalyzerOptions &getAnalyzerOptions() { return AOptions; }
124 typedef CheckerBase *CheckerRef;
125 typedef const void *CheckerTag;
126 typedef CheckerFn<void ()> CheckerDtor;
128 //===----------------------------------------------------------------------===//
130 //===----------------------------------------------------------------------===//
132 /// \brief Used to register checkers.
134 /// \returns a pointer to the checker object.
135 template <typename CHECKER>
136 CHECKER *registerChecker() {
137 CheckerTag tag = getTag<CHECKER>();
138 CheckerRef &ref = CheckerTags[tag];
140 return static_cast<CHECKER *>(ref); // already registered.
142 CHECKER *checker = new CHECKER();
143 checker->Name = CurrentCheckName;
144 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
145 CHECKER::_register(checker, *this);
150 template <typename CHECKER>
151 CHECKER *registerChecker(AnalyzerOptions &AOpts) {
152 CheckerTag tag = getTag<CHECKER>();
153 CheckerRef &ref = CheckerTags[tag];
155 return static_cast<CHECKER *>(ref); // already registered.
157 CHECKER *checker = new CHECKER(AOpts);
158 checker->Name = CurrentCheckName;
159 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
160 CHECKER::_register(checker, *this);
165 //===----------------------------------------------------------------------===//
166 // Functions for running checkers for AST traversing..
167 //===----------------------------------------------------------------------===//
169 /// \brief Run checkers handling Decls.
170 void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
173 /// \brief Run checkers handling Decls containing a Stmt body.
174 void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
177 //===----------------------------------------------------------------------===//
178 // Functions for running checkers for path-sensitive checking.
179 //===----------------------------------------------------------------------===//
181 /// \brief Run checkers for pre-visiting Stmts.
183 /// The notification is performed for every explored CFGElement, which does
184 /// not include the control flow statements such as IfStmt.
186 /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
187 void runCheckersForPreStmt(ExplodedNodeSet &Dst,
188 const ExplodedNodeSet &Src,
191 runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
194 /// \brief Run checkers for post-visiting Stmts.
196 /// The notification is performed for every explored CFGElement, which does
197 /// not include the control flow statements such as IfStmt.
199 /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
200 void runCheckersForPostStmt(ExplodedNodeSet &Dst,
201 const ExplodedNodeSet &Src,
204 bool wasInlined = false) {
205 runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
208 /// \brief Run checkers for visiting Stmts.
209 void runCheckersForStmt(bool isPreVisit,
210 ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
211 const Stmt *S, ExprEngine &Eng,
212 bool wasInlined = false);
214 /// \brief Run checkers for pre-visiting obj-c messages.
215 void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
216 const ExplodedNodeSet &Src,
217 const ObjCMethodCall &msg,
219 runCheckersForObjCMessage(ObjCMessageVisitKind::Pre, Dst, Src, msg, Eng);
222 /// \brief Run checkers for post-visiting obj-c messages.
223 void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
224 const ExplodedNodeSet &Src,
225 const ObjCMethodCall &msg,
227 bool wasInlined = false) {
228 runCheckersForObjCMessage(ObjCMessageVisitKind::Post, Dst, Src, msg, Eng,
232 /// \brief Run checkers for visiting an obj-c message to nil.
233 void runCheckersForObjCMessageNil(ExplodedNodeSet &Dst,
234 const ExplodedNodeSet &Src,
235 const ObjCMethodCall &msg,
237 runCheckersForObjCMessage(ObjCMessageVisitKind::MessageNil, Dst, Src, msg,
242 /// \brief Run checkers for visiting obj-c messages.
243 void runCheckersForObjCMessage(ObjCMessageVisitKind visitKind,
244 ExplodedNodeSet &Dst,
245 const ExplodedNodeSet &Src,
246 const ObjCMethodCall &msg, ExprEngine &Eng,
247 bool wasInlined = false);
249 /// \brief Run checkers for pre-visiting obj-c messages.
250 void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
251 const CallEvent &Call, ExprEngine &Eng) {
252 runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
255 /// \brief Run checkers for post-visiting obj-c messages.
256 void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
257 const CallEvent &Call, ExprEngine &Eng,
258 bool wasInlined = false) {
259 runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
263 /// \brief Run checkers for visiting obj-c messages.
264 void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
265 const ExplodedNodeSet &Src,
266 const CallEvent &Call, ExprEngine &Eng,
267 bool wasInlined = false);
269 /// \brief Run checkers for load/store of a location.
270 void runCheckersForLocation(ExplodedNodeSet &Dst,
271 const ExplodedNodeSet &Src,
278 /// \brief Run checkers for binding of a value to a location.
279 void runCheckersForBind(ExplodedNodeSet &Dst,
280 const ExplodedNodeSet &Src,
281 SVal location, SVal val,
282 const Stmt *S, ExprEngine &Eng,
283 const ProgramPoint &PP);
285 /// \brief Run checkers for end of analysis.
286 void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
289 /// \brief Run checkers on begining of function.
290 void runCheckersForBeginFunction(ExplodedNodeSet &Dst,
295 /// \brief Run checkers on end of function.
296 void runCheckersForEndFunction(NodeBuilderContext &BC,
297 ExplodedNodeSet &Dst,
301 /// \brief Run checkers for branch condition.
302 void runCheckersForBranchCondition(const Stmt *condition,
303 ExplodedNodeSet &Dst, ExplodedNode *Pred,
306 /// \brief Run checkers for live symbols.
308 /// Allows modifying SymbolReaper object. For example, checkers can explicitly
309 /// register symbols of interest as live. These symbols will not be marked
310 /// dead and removed.
311 void runCheckersForLiveSymbols(ProgramStateRef state,
312 SymbolReaper &SymReaper);
314 /// \brief Run checkers for dead symbols.
316 /// Notifies checkers when symbols become dead. For example, this allows
317 /// checkers to aggressively clean up/reduce the checker state and produce
318 /// precise diagnostics.
319 void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
320 const ExplodedNodeSet &Src,
321 SymbolReaper &SymReaper, const Stmt *S,
323 ProgramPoint::Kind K);
325 /// \brief Run checkers for region changes.
327 /// This corresponds to the check::RegionChanges callback.
328 /// \param state The current program state.
329 /// \param invalidated A set of all symbols potentially touched by the change.
330 /// \param ExplicitRegions The regions explicitly requested for invalidation.
331 /// For example, in the case of a function call, these would be arguments.
332 /// \param Regions The transitive closure of accessible regions,
333 /// i.e. all regions that may have been touched by this change.
334 /// \param Call The call expression wrapper if the regions are invalidated
337 runCheckersForRegionChanges(ProgramStateRef state,
338 const InvalidatedSymbols *invalidated,
339 ArrayRef<const MemRegion *> ExplicitRegions,
340 ArrayRef<const MemRegion *> Regions,
341 const CallEvent *Call);
343 /// \brief Run checkers when pointers escape.
345 /// This notifies the checkers about pointer escape, which occurs whenever
346 /// the analyzer cannot track the symbol any more. For example, as a
347 /// result of assigning a pointer into a global or when it's passed to a
348 /// function call the analyzer cannot model.
350 /// \param State The state at the point of escape.
351 /// \param Escaped The list of escaped symbols.
352 /// \param Call The corresponding CallEvent, if the symbols escape as
353 /// parameters to the given call.
354 /// \param Kind The reason of pointer escape.
355 /// \param ITraits Information about invalidation for a particular
357 /// \returns Checkers can modify the state by returning a new one.
359 runCheckersForPointerEscape(ProgramStateRef State,
360 const InvalidatedSymbols &Escaped,
361 const CallEvent *Call,
362 PointerEscapeKind Kind,
363 RegionAndSymbolInvalidationTraits *ITraits);
365 /// \brief Run checkers for handling assumptions on symbolic values.
366 ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
367 SVal Cond, bool Assumption);
369 /// \brief Run checkers for evaluating a call.
371 /// Warning: Currently, the CallEvent MUST come from a CallExpr!
372 void runCheckersForEvalCall(ExplodedNodeSet &Dst,
373 const ExplodedNodeSet &Src,
374 const CallEvent &CE, ExprEngine &Eng);
376 /// \brief Run checkers for the entire Translation Unit.
377 void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
378 AnalysisManager &mgr,
381 /// \brief Run checkers for debug-printing a ProgramState.
383 /// Unlike most other callbacks, any checker can simply implement the virtual
384 /// method CheckerBase::printState if it has custom data to print.
385 /// \param Out The output stream
386 /// \param State The state being printed
387 /// \param NL The preferred representation of a newline.
388 /// \param Sep The preferred separator between different kinds of data.
389 void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
390 const char *NL, const char *Sep);
392 //===----------------------------------------------------------------------===//
393 // Internal registration functions for AST traversing.
394 //===----------------------------------------------------------------------===//
396 // Functions used by the registration mechanism, checkers should not touch
399 typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
402 typedef bool (*HandlesDeclFunc)(const Decl *D);
403 void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
405 void _registerForBody(CheckDeclFunc checkfn);
407 //===----------------------------------------------------------------------===//
408 // Internal registration functions for path-sensitive checking.
409 //===----------------------------------------------------------------------===//
411 typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
413 typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
414 CheckObjCMessageFunc;
416 typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
419 typedef CheckerFn<void (const SVal &location, bool isLoad,
424 typedef CheckerFn<void (const SVal &location, const SVal &val,
425 const Stmt *S, CheckerContext &)>
428 typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
429 CheckEndAnalysisFunc;
431 typedef CheckerFn<void (CheckerContext &)>
432 CheckBeginFunctionFunc;
434 typedef CheckerFn<void (CheckerContext &)>
435 CheckEndFunctionFunc;
437 typedef CheckerFn<void (const Stmt *, CheckerContext &)>
438 CheckBranchConditionFunc;
440 typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
441 CheckDeadSymbolsFunc;
443 typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
445 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
446 const InvalidatedSymbols *symbols,
447 ArrayRef<const MemRegion *> ExplicitRegions,
448 ArrayRef<const MemRegion *> Regions,
449 const CallEvent *Call)>
450 CheckRegionChangesFunc;
452 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
453 const InvalidatedSymbols &Escaped,
454 const CallEvent *Call,
455 PointerEscapeKind Kind,
456 RegionAndSymbolInvalidationTraits *ITraits)>
457 CheckPointerEscapeFunc;
459 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
460 const SVal &cond, bool assumption)>
463 typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
466 typedef CheckerFn<void (const TranslationUnitDecl *,
467 AnalysisManager&, BugReporter &)>
468 CheckEndOfTranslationUnit;
470 typedef bool (*HandlesStmtFunc)(const Stmt *D);
471 void _registerForPreStmt(CheckStmtFunc checkfn,
472 HandlesStmtFunc isForStmtFn);
473 void _registerForPostStmt(CheckStmtFunc checkfn,
474 HandlesStmtFunc isForStmtFn);
476 void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
477 void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
479 void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn);
481 void _registerForPreCall(CheckCallFunc checkfn);
482 void _registerForPostCall(CheckCallFunc checkfn);
484 void _registerForLocation(CheckLocationFunc checkfn);
486 void _registerForBind(CheckBindFunc checkfn);
488 void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
490 void _registerForBeginFunction(CheckEndFunctionFunc checkfn);
491 void _registerForEndFunction(CheckEndFunctionFunc checkfn);
493 void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
495 void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
497 void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
499 void _registerForRegionChanges(CheckRegionChangesFunc checkfn);
501 void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
503 void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
505 void _registerForEvalAssume(EvalAssumeFunc checkfn);
507 void _registerForEvalCall(EvalCallFunc checkfn);
509 void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
511 //===----------------------------------------------------------------------===//
512 // Internal registration functions for events.
513 //===----------------------------------------------------------------------===//
515 typedef void *EventTag;
516 typedef CheckerFn<void (const void *event)> CheckEventFunc;
518 template <typename EVENT>
519 void _registerListenerForEvent(CheckEventFunc checkfn) {
520 EventInfo &info = Events[getTag<EVENT>()];
521 info.Checkers.push_back(checkfn);
524 template <typename EVENT>
525 void _registerDispatcherForEvent() {
526 EventInfo &info = Events[getTag<EVENT>()];
527 info.HasDispatcher = true;
530 template <typename EVENT>
531 void _dispatchEvent(const EVENT &event) const {
532 EventsTy::const_iterator I = Events.find(getTag<EVENT>());
533 if (I == Events.end())
535 const EventInfo &info = I->second;
536 for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
537 info.Checkers[i](&event);
540 //===----------------------------------------------------------------------===//
541 // Implementation details.
542 //===----------------------------------------------------------------------===//
545 template <typename CHECKER>
546 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
548 template <typename T>
549 static void *getTag() { static int tag; return &tag; }
551 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
553 std::vector<CheckerDtor> CheckerDtors;
555 struct DeclCheckerInfo {
556 CheckDeclFunc CheckFn;
557 HandlesDeclFunc IsForDeclFn;
559 std::vector<DeclCheckerInfo> DeclCheckers;
561 std::vector<CheckDeclFunc> BodyCheckers;
563 typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
564 typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
565 CachedDeclCheckersMapTy CachedDeclCheckersMap;
567 struct StmtCheckerInfo {
568 CheckStmtFunc CheckFn;
569 HandlesStmtFunc IsForStmtFn;
572 std::vector<StmtCheckerInfo> StmtCheckers;
574 typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
575 typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
576 CachedStmtCheckersMapTy CachedStmtCheckersMap;
578 const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
581 /// Returns the checkers that have registered for callbacks of the
583 const std::vector<CheckObjCMessageFunc> &
584 getObjCMessageCheckers(ObjCMessageVisitKind Kind);
586 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
587 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
588 std::vector<CheckObjCMessageFunc> ObjCMessageNilCheckers;
590 std::vector<CheckCallFunc> PreCallCheckers;
591 std::vector<CheckCallFunc> PostCallCheckers;
593 std::vector<CheckLocationFunc> LocationCheckers;
595 std::vector<CheckBindFunc> BindCheckers;
597 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
599 std::vector<CheckBeginFunctionFunc> BeginFunctionCheckers;
600 std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
602 std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
604 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
606 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
608 std::vector<CheckRegionChangesFunc> RegionChangesCheckers;
610 std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
612 std::vector<EvalAssumeFunc> EvalAssumeCheckers;
614 std::vector<EvalCallFunc> EvalCallCheckers;
616 std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
619 SmallVector<CheckEventFunc, 4> Checkers;
621 EventInfo() : HasDispatcher(false) { }
624 typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
628 } // end ento namespace
630 } // end clang namespace