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_SA_CORE_CHECKERMANAGER_H
15 #define LLVM_CLANG_SA_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 P1, typename P2, typename P3, typename P4,
52 class CheckerFn<RET(P1, P2, P3, P4, P5)> {
53 typedef RET (*Func)(void *, P1, P2, P3, P4, P5);
57 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
58 RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const {
59 return Fn(Checker, p1, p2, p3, p4, p5);
63 template <typename RET, typename P1, typename P2, typename P3, typename P4>
64 class CheckerFn<RET(P1, P2, P3, P4)> {
65 typedef RET (*Func)(void *, P1, P2, P3, P4);
69 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
70 RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
71 return Fn(Checker, p1, p2, p3, p4);
75 template <typename RET, typename P1, typename P2, typename P3>
76 class CheckerFn<RET(P1, P2, P3)> {
77 typedef RET (*Func)(void *, P1, P2, P3);
81 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
82 RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
85 template <typename RET, typename P1, typename P2>
86 class CheckerFn<RET(P1, P2)> {
87 typedef RET (*Func)(void *, P1, P2);
91 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
92 RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
95 template <typename RET, typename P1>
96 class CheckerFn<RET(P1)> {
97 typedef RET (*Func)(void *, P1);
100 CheckerBase *Checker;
101 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
102 RET operator()(P1 p1) const { return Fn(Checker, p1); }
105 template <typename RET>
106 class CheckerFn<RET()> {
107 typedef RET (*Func)(void *);
110 CheckerBase *Checker;
111 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
112 RET operator()() const { return Fn(Checker); }
115 /// \brief Describes the different reasons a pointer escapes
117 enum PointerEscapeKind {
118 /// A pointer escapes due to binding its value to a location
119 /// that the analyzer cannot track.
122 /// The pointer has been passed to a function call directly.
123 PSK_DirectEscapeOnCall,
125 /// The pointer has been passed to a function indirectly.
126 /// For example, the pointer is accessible through an
127 /// argument to a function.
128 PSK_IndirectEscapeOnCall,
130 /// The reason for pointer escape is unknown. For example,
131 /// a region containing this pointer is invalidated.
135 // This wrapper is used to ensure that only StringRefs originating from the
136 // CheckerRegistry are used as check names. We want to make sure all check
137 // name strings have a lifetime that keeps them alive at least until the path
138 // diagnostics have been processed.
141 friend class ::clang::ento::CheckerRegistry;
142 explicit CheckName(StringRef Name) : Name(Name) {}
146 CheckName(const CheckName &Other) : Name(Other.Name) {}
147 StringRef getName() const { return Name; }
150 class CheckerManager {
151 const LangOptions LangOpts;
152 AnalyzerOptionsRef AOptions;
153 CheckName CurrentCheckName;
156 CheckerManager(const LangOptions &langOpts,
157 AnalyzerOptionsRef AOptions)
158 : LangOpts(langOpts),
159 AOptions(AOptions) {}
163 void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
164 CheckName getCurrentCheckName() const { return CurrentCheckName; }
166 bool hasPathSensitiveCheckers() const;
168 void finishedCheckerRegistration();
170 const LangOptions &getLangOpts() const { return LangOpts; }
171 AnalyzerOptions &getAnalyzerOptions() { return *AOptions; }
173 typedef CheckerBase *CheckerRef;
174 typedef const void *CheckerTag;
175 typedef CheckerFn<void ()> CheckerDtor;
177 //===----------------------------------------------------------------------===//
179 //===----------------------------------------------------------------------===//
181 /// \brief Used to register checkers.
183 /// \returns a pointer to the checker object.
184 template <typename CHECKER>
185 CHECKER *registerChecker() {
186 CheckerTag tag = getTag<CHECKER>();
187 CheckerRef &ref = CheckerTags[tag];
189 return static_cast<CHECKER *>(ref); // already registered.
191 CHECKER *checker = new CHECKER();
192 checker->Name = CurrentCheckName;
193 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
194 CHECKER::_register(checker, *this);
199 template <typename CHECKER>
200 CHECKER *registerChecker(AnalyzerOptions &AOpts) {
201 CheckerTag tag = getTag<CHECKER>();
202 CheckerRef &ref = CheckerTags[tag];
204 return static_cast<CHECKER *>(ref); // already registered.
206 CHECKER *checker = new CHECKER(AOpts);
207 checker->Name = CurrentCheckName;
208 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
209 CHECKER::_register(checker, *this);
214 //===----------------------------------------------------------------------===//
215 // Functions for running checkers for AST traversing..
216 //===----------------------------------------------------------------------===//
218 /// \brief Run checkers handling Decls.
219 void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
222 /// \brief Run checkers handling Decls containing a Stmt body.
223 void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
226 //===----------------------------------------------------------------------===//
227 // Functions for running checkers for path-sensitive checking.
228 //===----------------------------------------------------------------------===//
230 /// \brief Run checkers for pre-visiting Stmts.
232 /// The notification is performed for every explored CFGElement, which does
233 /// not include the control flow statements such as IfStmt.
235 /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
236 void runCheckersForPreStmt(ExplodedNodeSet &Dst,
237 const ExplodedNodeSet &Src,
240 runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
243 /// \brief Run checkers for post-visiting Stmts.
245 /// The notification is performed for every explored CFGElement, which does
246 /// not include the control flow statements such as IfStmt.
248 /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
249 void runCheckersForPostStmt(ExplodedNodeSet &Dst,
250 const ExplodedNodeSet &Src,
253 bool wasInlined = false) {
254 runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
257 /// \brief Run checkers for visiting Stmts.
258 void runCheckersForStmt(bool isPreVisit,
259 ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
260 const Stmt *S, ExprEngine &Eng,
261 bool wasInlined = false);
263 /// \brief Run checkers for pre-visiting obj-c messages.
264 void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
265 const ExplodedNodeSet &Src,
266 const ObjCMethodCall &msg,
268 runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
271 /// \brief Run checkers for post-visiting obj-c messages.
272 void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
273 const ExplodedNodeSet &Src,
274 const ObjCMethodCall &msg,
276 bool wasInlined = false) {
277 runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng,
281 /// \brief Run checkers for visiting obj-c messages.
282 void runCheckersForObjCMessage(bool isPreVisit,
283 ExplodedNodeSet &Dst,
284 const ExplodedNodeSet &Src,
285 const ObjCMethodCall &msg, ExprEngine &Eng,
286 bool wasInlined = false);
288 /// \brief Run checkers for pre-visiting obj-c messages.
289 void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
290 const CallEvent &Call, ExprEngine &Eng) {
291 runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
294 /// \brief Run checkers for post-visiting obj-c messages.
295 void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
296 const CallEvent &Call, ExprEngine &Eng,
297 bool wasInlined = false) {
298 runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
302 /// \brief Run checkers for visiting obj-c messages.
303 void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
304 const ExplodedNodeSet &Src,
305 const CallEvent &Call, ExprEngine &Eng,
306 bool wasInlined = false);
308 /// \brief Run checkers for load/store of a location.
309 void runCheckersForLocation(ExplodedNodeSet &Dst,
310 const ExplodedNodeSet &Src,
317 /// \brief Run checkers for binding of a value to a location.
318 void runCheckersForBind(ExplodedNodeSet &Dst,
319 const ExplodedNodeSet &Src,
320 SVal location, SVal val,
321 const Stmt *S, ExprEngine &Eng,
322 const ProgramPoint &PP);
324 /// \brief Run checkers for end of analysis.
325 void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
328 /// \brief Run checkers on end of function.
329 void runCheckersForEndFunction(NodeBuilderContext &BC,
330 ExplodedNodeSet &Dst,
334 /// \brief Run checkers for branch condition.
335 void runCheckersForBranchCondition(const Stmt *condition,
336 ExplodedNodeSet &Dst, ExplodedNode *Pred,
339 /// \brief Run checkers for live symbols.
341 /// Allows modifying SymbolReaper object. For example, checkers can explicitly
342 /// register symbols of interest as live. These symbols will not be marked
343 /// dead and removed.
344 void runCheckersForLiveSymbols(ProgramStateRef state,
345 SymbolReaper &SymReaper);
347 /// \brief Run checkers for dead symbols.
349 /// Notifies checkers when symbols become dead. For example, this allows
350 /// checkers to aggressively clean up/reduce the checker state and produce
351 /// precise diagnostics.
352 void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
353 const ExplodedNodeSet &Src,
354 SymbolReaper &SymReaper, const Stmt *S,
356 ProgramPoint::Kind K);
358 /// \brief True if at least one checker wants to check region changes.
359 bool wantsRegionChangeUpdate(ProgramStateRef state);
361 /// \brief Run checkers for region changes.
363 /// This corresponds to the check::RegionChanges callback.
364 /// \param state The current program state.
365 /// \param invalidated A set of all symbols potentially touched by the change.
366 /// \param ExplicitRegions The regions explicitly requested for invalidation.
367 /// For example, in the case of a function call, these would be arguments.
368 /// \param Regions The transitive closure of accessible regions,
369 /// i.e. all regions that may have been touched by this change.
370 /// \param Call The call expression wrapper if the regions are invalidated
373 runCheckersForRegionChanges(ProgramStateRef state,
374 const InvalidatedSymbols *invalidated,
375 ArrayRef<const MemRegion *> ExplicitRegions,
376 ArrayRef<const MemRegion *> Regions,
377 const CallEvent *Call);
379 /// \brief Run checkers when pointers escape.
381 /// This notifies the checkers about pointer escape, which occurs whenever
382 /// the analyzer cannot track the symbol any more. For example, as a
383 /// result of assigning a pointer into a global or when it's passed to a
384 /// function call the analyzer cannot model.
386 /// \param State The state at the point of escape.
387 /// \param Escaped The list of escaped symbols.
388 /// \param Call The corresponding CallEvent, if the symbols escape as
389 /// parameters to the given call.
390 /// \param Kind The reason of pointer escape.
391 /// \param ITraits Information about invalidation for a particular
393 /// \returns Checkers can modify the state by returning a new one.
395 runCheckersForPointerEscape(ProgramStateRef State,
396 const InvalidatedSymbols &Escaped,
397 const CallEvent *Call,
398 PointerEscapeKind Kind,
399 RegionAndSymbolInvalidationTraits *ITraits);
401 /// \brief Run checkers for handling assumptions on symbolic values.
402 ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
403 SVal Cond, bool Assumption);
405 /// \brief Run checkers for evaluating a call.
407 /// Warning: Currently, the CallEvent MUST come from a CallExpr!
408 void runCheckersForEvalCall(ExplodedNodeSet &Dst,
409 const ExplodedNodeSet &Src,
410 const CallEvent &CE, ExprEngine &Eng);
412 /// \brief Run checkers for the entire Translation Unit.
413 void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
414 AnalysisManager &mgr,
417 /// \brief Run checkers for debug-printing a ProgramState.
419 /// Unlike most other callbacks, any checker can simply implement the virtual
420 /// method CheckerBase::printState if it has custom data to print.
421 /// \param Out The output stream
422 /// \param State The state being printed
423 /// \param NL The preferred representation of a newline.
424 /// \param Sep The preferred separator between different kinds of data.
425 void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
426 const char *NL, const char *Sep);
428 //===----------------------------------------------------------------------===//
429 // Internal registration functions for AST traversing.
430 //===----------------------------------------------------------------------===//
432 // Functions used by the registration mechanism, checkers should not touch
435 typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
438 typedef bool (*HandlesDeclFunc)(const Decl *D);
439 void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
441 void _registerForBody(CheckDeclFunc checkfn);
443 //===----------------------------------------------------------------------===//
444 // Internal registration functions for path-sensitive checking.
445 //===----------------------------------------------------------------------===//
447 typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
449 typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
450 CheckObjCMessageFunc;
452 typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
455 typedef CheckerFn<void (const SVal &location, bool isLoad,
460 typedef CheckerFn<void (const SVal &location, const SVal &val,
461 const Stmt *S, CheckerContext &)>
464 typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
465 CheckEndAnalysisFunc;
467 typedef CheckerFn<void (CheckerContext &)>
468 CheckEndFunctionFunc;
470 typedef CheckerFn<void (const Stmt *, CheckerContext &)>
471 CheckBranchConditionFunc;
473 typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
474 CheckDeadSymbolsFunc;
476 typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
478 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
479 const InvalidatedSymbols *symbols,
480 ArrayRef<const MemRegion *> ExplicitRegions,
481 ArrayRef<const MemRegion *> Regions,
482 const CallEvent *Call)>
483 CheckRegionChangesFunc;
485 typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
487 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
488 const InvalidatedSymbols &Escaped,
489 const CallEvent *Call,
490 PointerEscapeKind Kind,
491 RegionAndSymbolInvalidationTraits *ITraits)>
492 CheckPointerEscapeFunc;
494 typedef CheckerFn<ProgramStateRef (ProgramStateRef,
495 const SVal &cond, bool assumption)>
498 typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
501 typedef CheckerFn<void (const TranslationUnitDecl *,
502 AnalysisManager&, BugReporter &)>
503 CheckEndOfTranslationUnit;
505 typedef bool (*HandlesStmtFunc)(const Stmt *D);
506 void _registerForPreStmt(CheckStmtFunc checkfn,
507 HandlesStmtFunc isForStmtFn);
508 void _registerForPostStmt(CheckStmtFunc checkfn,
509 HandlesStmtFunc isForStmtFn);
511 void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
512 void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
514 void _registerForPreCall(CheckCallFunc checkfn);
515 void _registerForPostCall(CheckCallFunc checkfn);
517 void _registerForLocation(CheckLocationFunc checkfn);
519 void _registerForBind(CheckBindFunc checkfn);
521 void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
523 void _registerForEndFunction(CheckEndFunctionFunc checkfn);
525 void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
527 void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
529 void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
531 void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
532 WantsRegionChangeUpdateFunc wantUpdateFn);
534 void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
536 void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
538 void _registerForEvalAssume(EvalAssumeFunc checkfn);
540 void _registerForEvalCall(EvalCallFunc checkfn);
542 void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
544 //===----------------------------------------------------------------------===//
545 // Internal registration functions for events.
546 //===----------------------------------------------------------------------===//
548 typedef void *EventTag;
549 typedef CheckerFn<void (const void *event)> CheckEventFunc;
551 template <typename EVENT>
552 void _registerListenerForEvent(CheckEventFunc checkfn) {
553 EventInfo &info = Events[getTag<EVENT>()];
554 info.Checkers.push_back(checkfn);
557 template <typename EVENT>
558 void _registerDispatcherForEvent() {
559 EventInfo &info = Events[getTag<EVENT>()];
560 info.HasDispatcher = true;
563 template <typename EVENT>
564 void _dispatchEvent(const EVENT &event) const {
565 EventsTy::const_iterator I = Events.find(getTag<EVENT>());
566 if (I == Events.end())
568 const EventInfo &info = I->second;
569 for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
570 info.Checkers[i](&event);
573 //===----------------------------------------------------------------------===//
574 // Implementation details.
575 //===----------------------------------------------------------------------===//
578 template <typename CHECKER>
579 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
581 template <typename T>
582 static void *getTag() { static int tag; return &tag; }
584 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
586 std::vector<CheckerDtor> CheckerDtors;
588 struct DeclCheckerInfo {
589 CheckDeclFunc CheckFn;
590 HandlesDeclFunc IsForDeclFn;
592 std::vector<DeclCheckerInfo> DeclCheckers;
594 std::vector<CheckDeclFunc> BodyCheckers;
596 typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
597 typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
598 CachedDeclCheckersMapTy CachedDeclCheckersMap;
600 struct StmtCheckerInfo {
601 CheckStmtFunc CheckFn;
602 HandlesStmtFunc IsForStmtFn;
605 std::vector<StmtCheckerInfo> StmtCheckers;
607 typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
608 typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
609 CachedStmtCheckersMapTy CachedStmtCheckersMap;
611 const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
614 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
615 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
617 std::vector<CheckCallFunc> PreCallCheckers;
618 std::vector<CheckCallFunc> PostCallCheckers;
620 std::vector<CheckLocationFunc> LocationCheckers;
622 std::vector<CheckBindFunc> BindCheckers;
624 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
626 std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
628 std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
630 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
632 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
634 struct RegionChangesCheckerInfo {
635 CheckRegionChangesFunc CheckFn;
636 WantsRegionChangeUpdateFunc WantUpdateFn;
638 std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
640 std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
642 std::vector<EvalAssumeFunc> EvalAssumeCheckers;
644 std::vector<EvalCallFunc> EvalCallCheckers;
646 std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
649 SmallVector<CheckEventFunc, 4> Checkers;
651 EventInfo() : HasDispatcher(false) { }
654 typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
658 } // end ento namespace
660 } // end clang namespace