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) {}
92 CheckName() = default;
93 StringRef getName() const { return Name; }
96 enum class ObjCMessageVisitKind {
102 class CheckerManager {
103 const LangOptions LangOpts;
104 AnalyzerOptionsRef AOptions;
105 CheckName CurrentCheckName;
108 CheckerManager(const LangOptions &langOpts,
109 AnalyzerOptionsRef AOptions)
110 : LangOpts(langOpts),
111 AOptions(AOptions) {}
115 void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
116 CheckName getCurrentCheckName() const { return CurrentCheckName; }
118 bool hasPathSensitiveCheckers() const;
120 void finishedCheckerRegistration();
122 const LangOptions &getLangOpts() const { return LangOpts; }
123 AnalyzerOptions &getAnalyzerOptions() { return *AOptions; }
125 typedef CheckerBase *CheckerRef;
126 typedef const void *CheckerTag;
127 typedef CheckerFn<void ()> CheckerDtor;
129 //===----------------------------------------------------------------------===//
131 //===----------------------------------------------------------------------===//
133 /// \brief Used to register checkers.
135 /// \returns a pointer to the checker object.
136 template <typename CHECKER>
137 CHECKER *registerChecker() {
138 CheckerTag tag = getTag<CHECKER>();
139 CheckerRef &ref = CheckerTags[tag];
141 return static_cast<CHECKER *>(ref); // already registered.
143 CHECKER *checker = new CHECKER();
144 checker->Name = CurrentCheckName;
145 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
146 CHECKER::_register(checker, *this);
151 template <typename CHECKER>
152 CHECKER *registerChecker(AnalyzerOptions &AOpts) {
153 CheckerTag tag = getTag<CHECKER>();
154 CheckerRef &ref = CheckerTags[tag];
156 return static_cast<CHECKER *>(ref); // already registered.
158 CHECKER *checker = new CHECKER(AOpts);
159 checker->Name = CurrentCheckName;
160 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
161 CHECKER::_register(checker, *this);
166 //===----------------------------------------------------------------------===//
167 // Functions for running checkers for AST traversing..
168 //===----------------------------------------------------------------------===//
170 /// \brief Run checkers handling Decls.
171 void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
174 /// \brief Run checkers handling Decls containing a Stmt body.
175 void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
178 //===----------------------------------------------------------------------===//
179 // Functions for running checkers for path-sensitive checking.
180 //===----------------------------------------------------------------------===//
182 /// \brief Run checkers for pre-visiting Stmts.
184 /// The notification is performed for every explored CFGElement, which does
185 /// not include the control flow statements such as IfStmt.
187 /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
188 void runCheckersForPreStmt(ExplodedNodeSet &Dst,
189 const ExplodedNodeSet &Src,
192 runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
195 /// \brief Run checkers for post-visiting Stmts.
197 /// The notification is performed for every explored CFGElement, which does
198 /// not include the control flow statements such as IfStmt.
200 /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
201 void runCheckersForPostStmt(ExplodedNodeSet &Dst,
202 const ExplodedNodeSet &Src,
205 bool wasInlined = false) {
206 runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
209 /// \brief Run checkers for visiting Stmts.
210 void runCheckersForStmt(bool isPreVisit,
211 ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
212 const Stmt *S, ExprEngine &Eng,
213 bool wasInlined = false);
215 /// \brief Run checkers for pre-visiting obj-c messages.
216 void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
217 const ExplodedNodeSet &Src,
218 const ObjCMethodCall &msg,
220 runCheckersForObjCMessage(ObjCMessageVisitKind::Pre, Dst, Src, msg, Eng);
223 /// \brief Run checkers for post-visiting obj-c messages.
224 void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
225 const ExplodedNodeSet &Src,
226 const ObjCMethodCall &msg,
228 bool wasInlined = false) {
229 runCheckersForObjCMessage(ObjCMessageVisitKind::Post, Dst, Src, msg, Eng,
233 /// \brief Run checkers for visiting an obj-c message to nil.
234 void runCheckersForObjCMessageNil(ExplodedNodeSet &Dst,
235 const ExplodedNodeSet &Src,
236 const ObjCMethodCall &msg,
238 runCheckersForObjCMessage(ObjCMessageVisitKind::MessageNil, Dst, Src, msg,
243 /// \brief Run checkers for visiting obj-c messages.
244 void runCheckersForObjCMessage(ObjCMessageVisitKind visitKind,
245 ExplodedNodeSet &Dst,
246 const ExplodedNodeSet &Src,
247 const ObjCMethodCall &msg, ExprEngine &Eng,
248 bool wasInlined = false);
250 /// \brief Run checkers for pre-visiting obj-c messages.
251 void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
252 const CallEvent &Call, ExprEngine &Eng) {
253 runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
256 /// \brief Run checkers for post-visiting obj-c messages.
257 void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
258 const CallEvent &Call, ExprEngine &Eng,
259 bool wasInlined = false) {
260 runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
264 /// \brief Run checkers for visiting obj-c messages.
265 void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
266 const ExplodedNodeSet &Src,
267 const CallEvent &Call, ExprEngine &Eng,
268 bool wasInlined = false);
270 /// \brief Run checkers for load/store of a location.
271 void runCheckersForLocation(ExplodedNodeSet &Dst,
272 const ExplodedNodeSet &Src,
279 /// \brief Run checkers for binding of a value to a location.
280 void runCheckersForBind(ExplodedNodeSet &Dst,
281 const ExplodedNodeSet &Src,
282 SVal location, SVal val,
283 const Stmt *S, ExprEngine &Eng,
284 const ProgramPoint &PP);
286 /// \brief Run checkers for end of analysis.
287 void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
290 /// \brief Run checkers on end of function.
291 void runCheckersForEndFunction(NodeBuilderContext &BC,
292 ExplodedNodeSet &Dst,
296 /// \brief Run checkers for branch condition.
297 void runCheckersForBranchCondition(const Stmt *condition,
298 ExplodedNodeSet &Dst, ExplodedNode *Pred,
301 /// \brief Run checkers for live symbols.
303 /// Allows modifying SymbolReaper object. For example, checkers can explicitly
304 /// register symbols of interest as live. These symbols will not be marked
305 /// dead and removed.
306 void runCheckersForLiveSymbols(ProgramStateRef state,
307 SymbolReaper &SymReaper);
309 /// \brief Run checkers for dead symbols.
311 /// Notifies checkers when symbols become dead. For example, this allows
312 /// checkers to aggressively clean up/reduce the checker state and produce
313 /// precise diagnostics.
314 void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
315 const ExplodedNodeSet &Src,
316 SymbolReaper &SymReaper, const Stmt *S,
318 ProgramPoint::Kind K);
320 /// \brief True if at least one checker wants to check region changes.
321 bool wantsRegionChangeUpdate(ProgramStateRef state);
323 /// \brief Run checkers for region changes.
325 /// This corresponds to the check::RegionChanges callback.
326 /// \param state The current program state.
327 /// \param invalidated A set of all symbols potentially touched by the change.
328 /// \param ExplicitRegions The regions explicitly requested for invalidation.
329 /// For example, in the case of a function call, these would be arguments.
330 /// \param Regions The transitive closure of accessible regions,
331 /// i.e. all regions that may have been touched by this change.
332 /// \param Call The call expression wrapper if the regions are invalidated
335 runCheckersForRegionChanges(ProgramStateRef state,
336 const InvalidatedSymbols *invalidated,
337 ArrayRef<const MemRegion *> ExplicitRegions,
338 ArrayRef<const MemRegion *> Regions,
339 const CallEvent *Call);
341 /// \brief Run checkers when pointers escape.
343 /// This notifies the checkers about pointer escape, which occurs whenever
344 /// the analyzer cannot track the symbol any more. For example, as a
345 /// result of assigning a pointer into a global or when it's passed to a
346 /// function call the analyzer cannot model.
348 /// \param State The state at the point of escape.
349 /// \param Escaped The list of escaped symbols.
350 /// \param Call The corresponding CallEvent, if the symbols escape as
351 /// parameters to the given call.
352 /// \param Kind The reason of pointer escape.
353 /// \param ITraits Information about invalidation for a particular
355 /// \returns Checkers can modify the state by returning a new one.
357 runCheckersForPointerEscape(ProgramStateRef State,
358 const InvalidatedSymbols &Escaped,
359 const CallEvent *Call,
360 PointerEscapeKind Kind,
361 RegionAndSymbolInvalidationTraits *ITraits);
363 /// \brief Run checkers for handling assumptions on symbolic values.
364 ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
365 SVal Cond, bool Assumption);
367 /// \brief Run checkers for evaluating a call.
369 /// Warning: Currently, the CallEvent MUST come from a CallExpr!
370 void runCheckersForEvalCall(ExplodedNodeSet &Dst,
371 const ExplodedNodeSet &Src,
372 const CallEvent &CE, ExprEngine &Eng);
374 /// \brief Run checkers for the entire Translation Unit.
375 void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
376 AnalysisManager &mgr,
379 /// \brief Run checkers for debug-printing a ProgramState.
381 /// Unlike most other callbacks, any checker can simply implement the virtual
382 /// method CheckerBase::printState if it has custom data to print.
383 /// \param Out The output stream
384 /// \param State The state being printed
385 /// \param NL The preferred representation of a newline.
386 /// \param Sep The preferred separator between different kinds of data.
387 void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
388 const char *NL, const char *Sep);
390 //===----------------------------------------------------------------------===//
391 // Internal registration functions for AST traversing.
392 //===----------------------------------------------------------------------===//
394 // Functions used by the registration mechanism, checkers should not touch
397 typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
400 typedef bool (*HandlesDeclFunc)(const Decl *D);
401 void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
403 void _registerForBody(CheckDeclFunc checkfn);
405 //===----------------------------------------------------------------------===//
406 // Internal registration functions for path-sensitive checking.
407 //===----------------------------------------------------------------------===//
409 typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
411 typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
412 CheckObjCMessageFunc;
414 typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
417 typedef CheckerFn<void (const SVal &location, bool isLoad,
422 typedef CheckerFn<void (const SVal &location, const SVal &val,
423 const Stmt *S, CheckerContext &)>
426 typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
427 CheckEndAnalysisFunc;
429 typedef CheckerFn<void (CheckerContext &)>
430 CheckEndFunctionFunc;
432 typedef CheckerFn<void (const Stmt *, CheckerContext &)>
433 CheckBranchConditionFunc;
435 typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
436 CheckDeadSymbolsFunc;
438 typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
440 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
441 const InvalidatedSymbols *symbols,
442 ArrayRef<const MemRegion *> ExplicitRegions,
443 ArrayRef<const MemRegion *> Regions,
444 const CallEvent *Call)>
445 CheckRegionChangesFunc;
447 typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
449 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
450 const InvalidatedSymbols &Escaped,
451 const CallEvent *Call,
452 PointerEscapeKind Kind,
453 RegionAndSymbolInvalidationTraits *ITraits)>
454 CheckPointerEscapeFunc;
456 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
457 const SVal &cond, bool assumption)>
460 typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
463 typedef CheckerFn<void (const TranslationUnitDecl *,
464 AnalysisManager&, BugReporter &)>
465 CheckEndOfTranslationUnit;
467 typedef bool (*HandlesStmtFunc)(const Stmt *D);
468 void _registerForPreStmt(CheckStmtFunc checkfn,
469 HandlesStmtFunc isForStmtFn);
470 void _registerForPostStmt(CheckStmtFunc checkfn,
471 HandlesStmtFunc isForStmtFn);
473 void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
474 void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
476 void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn);
478 void _registerForPreCall(CheckCallFunc checkfn);
479 void _registerForPostCall(CheckCallFunc checkfn);
481 void _registerForLocation(CheckLocationFunc checkfn);
483 void _registerForBind(CheckBindFunc checkfn);
485 void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
487 void _registerForEndFunction(CheckEndFunctionFunc checkfn);
489 void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
491 void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
493 void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
495 void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
496 WantsRegionChangeUpdateFunc wantUpdateFn);
498 void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
500 void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
502 void _registerForEvalAssume(EvalAssumeFunc checkfn);
504 void _registerForEvalCall(EvalCallFunc checkfn);
506 void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
508 //===----------------------------------------------------------------------===//
509 // Internal registration functions for events.
510 //===----------------------------------------------------------------------===//
512 typedef void *EventTag;
513 typedef CheckerFn<void (const void *event)> CheckEventFunc;
515 template <typename EVENT>
516 void _registerListenerForEvent(CheckEventFunc checkfn) {
517 EventInfo &info = Events[getTag<EVENT>()];
518 info.Checkers.push_back(checkfn);
521 template <typename EVENT>
522 void _registerDispatcherForEvent() {
523 EventInfo &info = Events[getTag<EVENT>()];
524 info.HasDispatcher = true;
527 template <typename EVENT>
528 void _dispatchEvent(const EVENT &event) const {
529 EventsTy::const_iterator I = Events.find(getTag<EVENT>());
530 if (I == Events.end())
532 const EventInfo &info = I->second;
533 for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
534 info.Checkers[i](&event);
537 //===----------------------------------------------------------------------===//
538 // Implementation details.
539 //===----------------------------------------------------------------------===//
542 template <typename CHECKER>
543 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
545 template <typename T>
546 static void *getTag() { static int tag; return &tag; }
548 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
550 std::vector<CheckerDtor> CheckerDtors;
552 struct DeclCheckerInfo {
553 CheckDeclFunc CheckFn;
554 HandlesDeclFunc IsForDeclFn;
556 std::vector<DeclCheckerInfo> DeclCheckers;
558 std::vector<CheckDeclFunc> BodyCheckers;
560 typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
561 typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
562 CachedDeclCheckersMapTy CachedDeclCheckersMap;
564 struct StmtCheckerInfo {
565 CheckStmtFunc CheckFn;
566 HandlesStmtFunc IsForStmtFn;
569 std::vector<StmtCheckerInfo> StmtCheckers;
571 typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
572 typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
573 CachedStmtCheckersMapTy CachedStmtCheckersMap;
575 const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
578 /// Returns the checkers that have registered for callbacks of the
580 const std::vector<CheckObjCMessageFunc> &
581 getObjCMessageCheckers(ObjCMessageVisitKind Kind);
583 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
584 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
585 std::vector<CheckObjCMessageFunc> ObjCMessageNilCheckers;
587 std::vector<CheckCallFunc> PreCallCheckers;
588 std::vector<CheckCallFunc> PostCallCheckers;
590 std::vector<CheckLocationFunc> LocationCheckers;
592 std::vector<CheckBindFunc> BindCheckers;
594 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
596 std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
598 std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
600 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
602 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
604 struct RegionChangesCheckerInfo {
605 CheckRegionChangesFunc CheckFn;
606 WantsRegionChangeUpdateFunc WantUpdateFn;
608 std::vector<RegionChangesCheckerInfo> 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