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 beginning 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 LocationContext *LCtx,
342 const CallEvent *Call);
344 /// \brief Run checkers when pointers escape.
346 /// This notifies the checkers about pointer escape, which occurs whenever
347 /// the analyzer cannot track the symbol any more. For example, as a
348 /// result of assigning a pointer into a global or when it's passed to a
349 /// function call the analyzer cannot model.
351 /// \param State The state at the point of escape.
352 /// \param Escaped The list of escaped symbols.
353 /// \param Call The corresponding CallEvent, if the symbols escape as
354 /// parameters to the given call.
355 /// \param Kind The reason of pointer escape.
356 /// \param ITraits Information about invalidation for a particular
358 /// \returns Checkers can modify the state by returning a new one.
360 runCheckersForPointerEscape(ProgramStateRef State,
361 const InvalidatedSymbols &Escaped,
362 const CallEvent *Call,
363 PointerEscapeKind Kind,
364 RegionAndSymbolInvalidationTraits *ITraits);
366 /// \brief Run checkers for handling assumptions on symbolic values.
367 ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
368 SVal Cond, bool Assumption);
370 /// \brief Run checkers for evaluating a call.
372 /// Warning: Currently, the CallEvent MUST come from a CallExpr!
373 void runCheckersForEvalCall(ExplodedNodeSet &Dst,
374 const ExplodedNodeSet &Src,
375 const CallEvent &CE, ExprEngine &Eng);
377 /// \brief Run checkers for the entire Translation Unit.
378 void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
379 AnalysisManager &mgr,
382 /// \brief Run checkers for debug-printing a ProgramState.
384 /// Unlike most other callbacks, any checker can simply implement the virtual
385 /// method CheckerBase::printState if it has custom data to print.
386 /// \param Out The output stream
387 /// \param State The state being printed
388 /// \param NL The preferred representation of a newline.
389 /// \param Sep The preferred separator between different kinds of data.
390 void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
391 const char *NL, const char *Sep);
393 //===----------------------------------------------------------------------===//
394 // Internal registration functions for AST traversing.
395 //===----------------------------------------------------------------------===//
397 // Functions used by the registration mechanism, checkers should not touch
400 typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
403 typedef bool (*HandlesDeclFunc)(const Decl *D);
404 void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
406 void _registerForBody(CheckDeclFunc checkfn);
408 //===----------------------------------------------------------------------===//
409 // Internal registration functions for path-sensitive checking.
410 //===----------------------------------------------------------------------===//
412 typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
414 typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
415 CheckObjCMessageFunc;
417 typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
420 typedef CheckerFn<void (const SVal &location, bool isLoad,
425 typedef CheckerFn<void (const SVal &location, const SVal &val,
426 const Stmt *S, CheckerContext &)>
429 typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
430 CheckEndAnalysisFunc;
432 typedef CheckerFn<void (CheckerContext &)>
433 CheckBeginFunctionFunc;
435 typedef CheckerFn<void (CheckerContext &)>
436 CheckEndFunctionFunc;
438 typedef CheckerFn<void (const Stmt *, CheckerContext &)>
439 CheckBranchConditionFunc;
441 typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
442 CheckDeadSymbolsFunc;
444 typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
446 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
447 const InvalidatedSymbols *symbols,
448 ArrayRef<const MemRegion *> ExplicitRegions,
449 ArrayRef<const MemRegion *> Regions,
450 const LocationContext *LCtx,
451 const CallEvent *Call)>
452 CheckRegionChangesFunc;
454 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
455 const InvalidatedSymbols &Escaped,
456 const CallEvent *Call,
457 PointerEscapeKind Kind,
458 RegionAndSymbolInvalidationTraits *ITraits)>
459 CheckPointerEscapeFunc;
461 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
462 const SVal &cond, bool assumption)>
465 typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
468 typedef CheckerFn<void (const TranslationUnitDecl *,
469 AnalysisManager&, BugReporter &)>
470 CheckEndOfTranslationUnit;
472 typedef bool (*HandlesStmtFunc)(const Stmt *D);
473 void _registerForPreStmt(CheckStmtFunc checkfn,
474 HandlesStmtFunc isForStmtFn);
475 void _registerForPostStmt(CheckStmtFunc checkfn,
476 HandlesStmtFunc isForStmtFn);
478 void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
479 void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
481 void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn);
483 void _registerForPreCall(CheckCallFunc checkfn);
484 void _registerForPostCall(CheckCallFunc checkfn);
486 void _registerForLocation(CheckLocationFunc checkfn);
488 void _registerForBind(CheckBindFunc checkfn);
490 void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
492 void _registerForBeginFunction(CheckEndFunctionFunc checkfn);
493 void _registerForEndFunction(CheckEndFunctionFunc checkfn);
495 void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
497 void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
499 void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
501 void _registerForRegionChanges(CheckRegionChangesFunc checkfn);
503 void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
505 void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
507 void _registerForEvalAssume(EvalAssumeFunc checkfn);
509 void _registerForEvalCall(EvalCallFunc checkfn);
511 void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
513 //===----------------------------------------------------------------------===//
514 // Internal registration functions for events.
515 //===----------------------------------------------------------------------===//
517 typedef void *EventTag;
518 typedef CheckerFn<void (const void *event)> CheckEventFunc;
520 template <typename EVENT>
521 void _registerListenerForEvent(CheckEventFunc checkfn) {
522 EventInfo &info = Events[getTag<EVENT>()];
523 info.Checkers.push_back(checkfn);
526 template <typename EVENT>
527 void _registerDispatcherForEvent() {
528 EventInfo &info = Events[getTag<EVENT>()];
529 info.HasDispatcher = true;
532 template <typename EVENT>
533 void _dispatchEvent(const EVENT &event) const {
534 EventsTy::const_iterator I = Events.find(getTag<EVENT>());
535 if (I == Events.end())
537 const EventInfo &info = I->second;
538 for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
539 info.Checkers[i](&event);
542 //===----------------------------------------------------------------------===//
543 // Implementation details.
544 //===----------------------------------------------------------------------===//
547 template <typename CHECKER>
548 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
550 template <typename T>
551 static void *getTag() { static int tag; return &tag; }
553 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
555 std::vector<CheckerDtor> CheckerDtors;
557 struct DeclCheckerInfo {
558 CheckDeclFunc CheckFn;
559 HandlesDeclFunc IsForDeclFn;
561 std::vector<DeclCheckerInfo> DeclCheckers;
563 std::vector<CheckDeclFunc> BodyCheckers;
565 typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
566 typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
567 CachedDeclCheckersMapTy CachedDeclCheckersMap;
569 struct StmtCheckerInfo {
570 CheckStmtFunc CheckFn;
571 HandlesStmtFunc IsForStmtFn;
574 std::vector<StmtCheckerInfo> StmtCheckers;
576 typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
577 typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
578 CachedStmtCheckersMapTy CachedStmtCheckersMap;
580 const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
583 /// Returns the checkers that have registered for callbacks of the
585 const std::vector<CheckObjCMessageFunc> &
586 getObjCMessageCheckers(ObjCMessageVisitKind Kind);
588 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
589 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
590 std::vector<CheckObjCMessageFunc> ObjCMessageNilCheckers;
592 std::vector<CheckCallFunc> PreCallCheckers;
593 std::vector<CheckCallFunc> PostCallCheckers;
595 std::vector<CheckLocationFunc> LocationCheckers;
597 std::vector<CheckBindFunc> BindCheckers;
599 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
601 std::vector<CheckBeginFunctionFunc> BeginFunctionCheckers;
602 std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
604 std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
606 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
608 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
610 std::vector<CheckRegionChangesFunc> RegionChangesCheckers;
612 std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
614 std::vector<EvalAssumeFunc> EvalAssumeCheckers;
616 std::vector<EvalCallFunc> EvalCallCheckers;
618 std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
621 SmallVector<CheckEventFunc, 4> Checkers;
623 EventInfo() : HasDispatcher(false) { }
626 typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
630 } // end ento namespace
632 } // end clang namespace