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/PathSensitive/ProgramState_Fwd.h"
20 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include "llvm/ADT/StringRef.h"
29 class AnalyzerOptions;
33 class LocationContext;
35 class TranslationUnitDecl;
39 class AnalysisManager;
44 class CheckerRegistry;
47 class ExplodedNodeSet;
50 struct NodeBuilderContext;
52 class RegionAndSymbolInvalidationTraits;
56 template <typename T> class CheckerFn;
58 template <typename RET, typename... Ps>
59 class CheckerFn<RET(Ps...)> {
60 using Func = RET (*)(void *, Ps...);
67 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) {}
69 RET operator()(Ps... ps) const {
70 return Fn(Checker, ps...);
74 /// Describes the different reasons a pointer escapes
76 enum PointerEscapeKind {
77 /// A pointer escapes due to binding its value to a location
78 /// that the analyzer cannot track.
81 /// The pointer has been passed to a function call directly.
82 PSK_DirectEscapeOnCall,
84 /// The pointer has been passed to a function indirectly.
85 /// For example, the pointer is accessible through an
86 /// argument to a function.
87 PSK_IndirectEscapeOnCall,
89 /// The reason for pointer escape is unknown. For example,
90 /// a region containing this pointer is invalidated.
94 // This wrapper is used to ensure that only StringRefs originating from the
95 // CheckerRegistry are used as check names. We want to make sure all check
96 // name strings have a lifetime that keeps them alive at least until the path
97 // diagnostics have been processed.
99 friend class ::clang::ento::CheckerRegistry;
103 explicit CheckName(StringRef Name) : Name(Name) {}
106 CheckName() = default;
108 StringRef getName() const { return Name; }
111 enum class ObjCMessageVisitKind {
117 class CheckerManager {
118 const LangOptions LangOpts;
119 AnalyzerOptions &AOptions;
120 CheckName CurrentCheckName;
123 CheckerManager(const LangOptions &langOpts, AnalyzerOptions &AOptions)
124 : LangOpts(langOpts), AOptions(AOptions) {}
128 void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
129 CheckName getCurrentCheckName() const { return CurrentCheckName; }
131 bool hasPathSensitiveCheckers() const;
133 void finishedCheckerRegistration();
135 const LangOptions &getLangOpts() const { return LangOpts; }
136 AnalyzerOptions &getAnalyzerOptions() { return AOptions; }
138 using CheckerRef = CheckerBase *;
139 using CheckerTag = const void *;
140 using CheckerDtor = CheckerFn<void ()>;
142 //===----------------------------------------------------------------------===//
144 //===----------------------------------------------------------------------===//
146 /// Used to register checkers.
147 /// All arguments are automatically passed through to the checker
150 /// \returns a pointer to the checker object.
151 template <typename CHECKER, typename... AT>
152 CHECKER *registerChecker(AT... Args) {
153 CheckerTag tag = getTag<CHECKER>();
154 CheckerRef &ref = CheckerTags[tag];
156 return static_cast<CHECKER *>(ref); // already registered.
158 CHECKER *checker = new CHECKER(Args...);
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 /// Run checkers handling Decls.
171 void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
174 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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,
242 /// 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 /// 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 /// 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 /// 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 /// Run checkers for load/store of a location.
270 void runCheckersForLocation(ExplodedNodeSet &Dst,
271 const ExplodedNodeSet &Src,
278 /// 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 /// Run checkers for end of analysis.
286 void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
289 /// Run checkers on beginning of function.
290 void runCheckersForBeginFunction(ExplodedNodeSet &Dst,
295 /// Run checkers on end of function.
296 void runCheckersForEndFunction(NodeBuilderContext &BC,
297 ExplodedNodeSet &Dst,
300 const ReturnStmt *RS);
302 /// Run checkers for branch condition.
303 void runCheckersForBranchCondition(const Stmt *condition,
304 ExplodedNodeSet &Dst, ExplodedNode *Pred,
307 /// Run checkers between C++ operator new and constructor calls.
308 void runCheckersForNewAllocator(const CXXNewExpr *NE, SVal Target,
309 ExplodedNodeSet &Dst,
312 bool wasInlined = false);
314 /// Run checkers for live symbols.
316 /// Allows modifying SymbolReaper object. For example, checkers can explicitly
317 /// register symbols of interest as live. These symbols will not be marked
318 /// dead and removed.
319 void runCheckersForLiveSymbols(ProgramStateRef state,
320 SymbolReaper &SymReaper);
322 /// Run checkers for dead symbols.
324 /// Notifies checkers when symbols become dead. For example, this allows
325 /// checkers to aggressively clean up/reduce the checker state and produce
326 /// precise diagnostics.
327 void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
328 const ExplodedNodeSet &Src,
329 SymbolReaper &SymReaper, const Stmt *S,
331 ProgramPoint::Kind K);
333 /// Run checkers for region changes.
335 /// This corresponds to the check::RegionChanges callback.
336 /// \param state The current program state.
337 /// \param invalidated A set of all symbols potentially touched by the change.
338 /// \param ExplicitRegions The regions explicitly requested for invalidation.
339 /// For example, in the case of a function call, these would be arguments.
340 /// \param Regions The transitive closure of accessible regions,
341 /// i.e. all regions that may have been touched by this change.
342 /// \param Call The call expression wrapper if the regions are invalidated
345 runCheckersForRegionChanges(ProgramStateRef state,
346 const InvalidatedSymbols *invalidated,
347 ArrayRef<const MemRegion *> ExplicitRegions,
348 ArrayRef<const MemRegion *> Regions,
349 const LocationContext *LCtx,
350 const CallEvent *Call);
352 /// Run checkers when pointers escape.
354 /// This notifies the checkers about pointer escape, which occurs whenever
355 /// the analyzer cannot track the symbol any more. For example, as a
356 /// result of assigning a pointer into a global or when it's passed to a
357 /// function call the analyzer cannot model.
359 /// \param State The state at the point of escape.
360 /// \param Escaped The list of escaped symbols.
361 /// \param Call The corresponding CallEvent, if the symbols escape as
362 /// parameters to the given call.
363 /// \param Kind The reason of pointer escape.
364 /// \param ITraits Information about invalidation for a particular
366 /// \returns Checkers can modify the state by returning a new one.
368 runCheckersForPointerEscape(ProgramStateRef State,
369 const InvalidatedSymbols &Escaped,
370 const CallEvent *Call,
371 PointerEscapeKind Kind,
372 RegionAndSymbolInvalidationTraits *ITraits);
374 /// Run checkers for handling assumptions on symbolic values.
375 ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
376 SVal Cond, bool Assumption);
378 /// Run checkers for evaluating a call.
380 /// Warning: Currently, the CallEvent MUST come from a CallExpr!
381 void runCheckersForEvalCall(ExplodedNodeSet &Dst,
382 const ExplodedNodeSet &Src,
383 const CallEvent &CE, ExprEngine &Eng);
385 /// Run checkers for the entire Translation Unit.
386 void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
387 AnalysisManager &mgr,
390 /// Run checkers for debug-printing a ProgramState.
392 /// Unlike most other callbacks, any checker can simply implement the virtual
393 /// method CheckerBase::printState if it has custom data to print.
394 /// \param Out The output stream
395 /// \param State The state being printed
396 /// \param NL The preferred representation of a newline.
397 /// \param Sep The preferred separator between different kinds of data.
398 void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
399 const char *NL, const char *Sep);
401 //===----------------------------------------------------------------------===//
402 // Internal registration functions for AST traversing.
403 //===----------------------------------------------------------------------===//
405 // Functions used by the registration mechanism, checkers should not touch
408 using CheckDeclFunc =
409 CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>;
411 using HandlesDeclFunc = bool (*)(const Decl *D);
413 void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
415 void _registerForBody(CheckDeclFunc checkfn);
417 //===----------------------------------------------------------------------===//
418 // Internal registration functions for path-sensitive checking.
419 //===----------------------------------------------------------------------===//
421 using CheckStmtFunc = CheckerFn<void (const Stmt *, CheckerContext &)>;
423 using CheckObjCMessageFunc =
424 CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>;
426 using CheckCallFunc =
427 CheckerFn<void (const CallEvent &, CheckerContext &)>;
429 using CheckLocationFunc =
430 CheckerFn<void (const SVal &location, bool isLoad, const Stmt *S,
433 using CheckBindFunc =
434 CheckerFn<void (const SVal &location, const SVal &val, const Stmt *S,
437 using CheckEndAnalysisFunc =
438 CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>;
440 using CheckBeginFunctionFunc = CheckerFn<void (CheckerContext &)>;
442 using CheckEndFunctionFunc =
443 CheckerFn<void (const ReturnStmt *, CheckerContext &)>;
445 using CheckBranchConditionFunc =
446 CheckerFn<void (const Stmt *, CheckerContext &)>;
448 using CheckNewAllocatorFunc =
449 CheckerFn<void (const CXXNewExpr *, SVal, CheckerContext &)>;
451 using CheckDeadSymbolsFunc =
452 CheckerFn<void (SymbolReaper &, CheckerContext &)>;
454 using CheckLiveSymbolsFunc = CheckerFn<void (ProgramStateRef,SymbolReaper &)>;
456 using CheckRegionChangesFunc =
457 CheckerFn<ProgramStateRef (ProgramStateRef,
458 const InvalidatedSymbols *symbols,
459 ArrayRef<const MemRegion *> ExplicitRegions,
460 ArrayRef<const MemRegion *> Regions,
461 const LocationContext *LCtx,
462 const CallEvent *Call)>;
464 using CheckPointerEscapeFunc =
465 CheckerFn<ProgramStateRef (ProgramStateRef,
466 const InvalidatedSymbols &Escaped,
467 const CallEvent *Call, PointerEscapeKind Kind,
468 RegionAndSymbolInvalidationTraits *ITraits)>;
470 using EvalAssumeFunc =
471 CheckerFn<ProgramStateRef (ProgramStateRef, const SVal &cond,
474 using EvalCallFunc = CheckerFn<bool (const CallExpr *, CheckerContext &)>;
476 using CheckEndOfTranslationUnit =
477 CheckerFn<void (const TranslationUnitDecl *, AnalysisManager &,
480 using HandlesStmtFunc = bool (*)(const Stmt *D);
482 void _registerForPreStmt(CheckStmtFunc checkfn,
483 HandlesStmtFunc isForStmtFn);
484 void _registerForPostStmt(CheckStmtFunc checkfn,
485 HandlesStmtFunc isForStmtFn);
487 void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
488 void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
490 void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn);
492 void _registerForPreCall(CheckCallFunc checkfn);
493 void _registerForPostCall(CheckCallFunc checkfn);
495 void _registerForLocation(CheckLocationFunc checkfn);
497 void _registerForBind(CheckBindFunc checkfn);
499 void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
501 void _registerForBeginFunction(CheckBeginFunctionFunc checkfn);
502 void _registerForEndFunction(CheckEndFunctionFunc checkfn);
504 void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
506 void _registerForNewAllocator(CheckNewAllocatorFunc checkfn);
508 void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
510 void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
512 void _registerForRegionChanges(CheckRegionChangesFunc checkfn);
514 void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
516 void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
518 void _registerForEvalAssume(EvalAssumeFunc checkfn);
520 void _registerForEvalCall(EvalCallFunc checkfn);
522 void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
524 //===----------------------------------------------------------------------===//
525 // Internal registration functions for events.
526 //===----------------------------------------------------------------------===//
528 using EventTag = void *;
529 using CheckEventFunc = CheckerFn<void (const void *event)>;
531 template <typename EVENT>
532 void _registerListenerForEvent(CheckEventFunc checkfn) {
533 EventInfo &info = Events[getTag<EVENT>()];
534 info.Checkers.push_back(checkfn);
537 template <typename EVENT>
538 void _registerDispatcherForEvent() {
539 EventInfo &info = Events[getTag<EVENT>()];
540 info.HasDispatcher = true;
543 template <typename EVENT>
544 void _dispatchEvent(const EVENT &event) const {
545 EventsTy::const_iterator I = Events.find(getTag<EVENT>());
546 if (I == Events.end())
548 const EventInfo &info = I->second;
549 for (const auto Checker : info.Checkers)
553 //===----------------------------------------------------------------------===//
554 // Implementation details.
555 //===----------------------------------------------------------------------===//
558 template <typename CHECKER>
559 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
561 template <typename T>
562 static void *getTag() { static int tag; return &tag; }
564 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
566 std::vector<CheckerDtor> CheckerDtors;
568 struct DeclCheckerInfo {
569 CheckDeclFunc CheckFn;
570 HandlesDeclFunc IsForDeclFn;
572 std::vector<DeclCheckerInfo> DeclCheckers;
574 std::vector<CheckDeclFunc> BodyCheckers;
576 using CachedDeclCheckers = SmallVector<CheckDeclFunc, 4>;
577 using CachedDeclCheckersMapTy = llvm::DenseMap<unsigned, CachedDeclCheckers>;
578 CachedDeclCheckersMapTy CachedDeclCheckersMap;
580 struct StmtCheckerInfo {
581 CheckStmtFunc CheckFn;
582 HandlesStmtFunc IsForStmtFn;
585 std::vector<StmtCheckerInfo> StmtCheckers;
587 using CachedStmtCheckers = SmallVector<CheckStmtFunc, 4>;
588 using CachedStmtCheckersMapTy = llvm::DenseMap<unsigned, CachedStmtCheckers>;
589 CachedStmtCheckersMapTy CachedStmtCheckersMap;
591 const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
594 /// Returns the checkers that have registered for callbacks of the
596 const std::vector<CheckObjCMessageFunc> &
597 getObjCMessageCheckers(ObjCMessageVisitKind Kind);
599 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
600 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
601 std::vector<CheckObjCMessageFunc> ObjCMessageNilCheckers;
603 std::vector<CheckCallFunc> PreCallCheckers;
604 std::vector<CheckCallFunc> PostCallCheckers;
606 std::vector<CheckLocationFunc> LocationCheckers;
608 std::vector<CheckBindFunc> BindCheckers;
610 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
612 std::vector<CheckBeginFunctionFunc> BeginFunctionCheckers;
613 std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
615 std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
617 std::vector<CheckNewAllocatorFunc> NewAllocatorCheckers;
619 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
621 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
623 std::vector<CheckRegionChangesFunc> RegionChangesCheckers;
625 std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
627 std::vector<EvalAssumeFunc> EvalAssumeCheckers;
629 std::vector<EvalCallFunc> EvalCallCheckers;
631 std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
634 SmallVector<CheckEventFunc, 4> Checkers;
635 bool HasDispatcher = false;
637 EventInfo() = default;
640 using EventsTy = llvm::DenseMap<EventTag, EventInfo>;
648 #endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H