CheckerManager.h revision 3682f1ea9c7fddc7dcbc590891158ba40f7fca16
1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===// 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// The LLVM Compiler Infrastructure 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// License. See LICENSE.TXT for details. 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//===----------------------------------------------------------------------===// 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Defines the Static Analyzer Checker Manager. 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===// 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "clang/Basic/LangOptions.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/ADT/SmallVector.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "llvm/ADT/DenseMap.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "llvm/ADT/FoldingSet.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "clang/Analysis/ProgramPoint.h" 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <vector> 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace clang { 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class Decl; 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class Stmt; 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class CallExpr; 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace ento { 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class CheckerBase; 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class ExprEngine; 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class AnalysisManager; 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class BugReporter; 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class CheckerContext; 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class SimpleCall; 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class ObjCMethodCall; 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class SVal; 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class ExplodedNode; 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class ExplodedNodeSet; 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class ExplodedGraph; 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class ProgramState; 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class NodeBuilder; 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct NodeBuilderContext; 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class MemRegion; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class SymbolReaper; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename T> class CheckerFn; 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename RET, typename P1, typename P2, typename P3, typename P4, 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typename P5> 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass CheckerFn<RET(P1, P2, P3, P4, P5)> { 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typedef RET (*Func)(void *, P1, P2, P3, P4, P5); 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Func Fn; 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdochpublic: 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CheckerBase *Checker; 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return Fn(Checker, p1, p2, p3, p4, p5); 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename RET, typename P1, typename P2, typename P3, typename P4> 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CheckerFn<RET(P1, P2, P3, P4)> { 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typedef RET (*Func)(void *, P1, P2, P3, P4); 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Func Fn; 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)public: 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CheckerBase *Checker; 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return Fn(Checker, p1, p2, p3, p4); 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename RET, typename P1, typename P2, typename P3> 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CheckerFn<RET(P1, P2, P3)> { 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef RET (*Func)(void *, P1, P2, P3); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Func Fn; 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)public: 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckerBase *Checker; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename RET, typename P1, typename P2> 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CheckerFn<RET(P1, P2)> { 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typedef RET (*Func)(void *, P1, P2); 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Func Fn; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)public: 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CheckerBase *Checker; 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename RET, typename P1> 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CheckerFn<RET(P1)> { 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typedef RET (*Func)(void *, P1); 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Func Fn; 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)public: 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckerBase *Checker; 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RET operator()(P1 p1) const { return Fn(Checker, p1); } 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename RET> 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CheckerFn<RET()> { 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typedef RET (*Func)(void *); 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Func Fn; 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)public: 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckerBase *Checker; 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RET operator()() const { return Fn(Checker); } 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CheckerManager { 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const LangOptions LangOpts; 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)public: 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { } 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ~CheckerManager(); 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool hasPathSensitiveCheckers() const; 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void finishedCheckerRegistration(); 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const LangOptions &getLangOpts() const { return LangOpts; } 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typedef CheckerBase *CheckerRef; 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef const void *CheckerTag; 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef CheckerFn<void ()> CheckerDtor; 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===// 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// registerChecker 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===// 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \brief Used to register checkers. 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \returns a pointer to the checker object. 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) template <typename CHECKER> 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECKER *registerChecker() { 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckerTag tag = getTag<CHECKER>(); 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckerRef &ref = CheckerTags[tag]; 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (ref) 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return static_cast<CHECKER *>(ref); // already registered. 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECKER *checker = new CHECKER(); 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>)); 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECKER::_register(checker, *this); 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ref = checker; 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return checker; 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===// 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Functions for running checkers for AST traversing.. 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===// 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \brief Run checkers handling Decls. 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BugReporter &BR); 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \brief Run checkers handling Decls containing a Stmt body. 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BugReporter &BR); 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===// 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Functions for running checkers for path-sensitive checking. 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===// 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \brief Run checkers for pre-visiting Stmts. 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// The notification is performed for every explored CFGElement, which does 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// not include the control flow statements such as IfStmt. 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \sa runCheckersForBranchCondition, runCheckersForPostStmt 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void runCheckersForPreStmt(ExplodedNodeSet &Dst, 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ExplodedNodeSet &Src, 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Stmt *S, 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ExprEngine &Eng) { 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng); 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \brief Run checkers for post-visiting Stmts. 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// The notification is performed for every explored CFGElement, which does 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// not include the control flow statements such as IfStmt. 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \sa runCheckersForBranchCondition, runCheckersForPreStmt 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void runCheckersForPostStmt(ExplodedNodeSet &Dst, 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ExplodedNodeSet &Src, 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Stmt *S, 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ExprEngine &Eng, 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool wasInlined = false) { 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined); 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \brief Run checkers for visiting Stmts. 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void runCheckersForStmt(bool isPreVisit, 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Stmt *S, ExprEngine &Eng, 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool wasInlined = false); 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \brief Run checkers for pre-visiting obj-c messages. 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ExplodedNodeSet &Src, 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ObjCMethodCall &msg, 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExprEngine &Eng) { 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng); 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /// \brief Run checkers for post-visiting obj-c messages. 211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, 212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const ExplodedNodeSet &Src, 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const ObjCMethodCall &msg, 214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExprEngine &Eng, 215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool wasInlined = false) { 216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng, 217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) wasInlined); 218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /// \brief Run checkers for visiting obj-c messages. 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void runCheckersForObjCMessage(bool isPreVisit, 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExplodedNodeSet &Dst, 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ExplodedNodeSet &Src, 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ObjCMethodCall &msg, ExprEngine &Eng, 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool wasInlined = false); 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /// \brief Run checkers for pre-visiting obj-c messages. 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const CallEvent &Call, ExprEngine &Eng) { 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng); 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /// \brief Run checkers for post-visiting obj-c messages. 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const CallEvent &Call, ExprEngine &Eng, 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool wasInlined = false) { 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng, 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) wasInlined); 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \brief Run checkers for visiting obj-c messages. 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst, 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ExplodedNodeSet &Src, 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const CallEvent &Call, ExprEngine &Eng, 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool wasInlined = false); 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \brief Run checkers for load/store of a location. 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void runCheckersForLocation(ExplodedNodeSet &Dst, 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ExplodedNodeSet &Src, 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SVal location, 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool isLoad, 252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const Stmt *NodeEx, 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const Stmt *BoundEx, 254e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch ExprEngine &Eng); 255e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch 256e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch /// \brief Run checkers for binding of a value to a location. 257e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch void runCheckersForBind(ExplodedNodeSet &Dst, 258e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch const ExplodedNodeSet &Src, 259ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch SVal location, SVal val, 260e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch const Stmt *S, ExprEngine &Eng, 261e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch const ProgramPoint &PP); 262e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /// \brief Run checkers for end of analysis. 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ExprEngine &Eng); 266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /// \brief Run checkers for end of path. 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void runCheckersForEndPath(NodeBuilderContext &BC, 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExplodedNodeSet &Dst, 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExprEngine &Eng); 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// \brief Run checkers for branch condition. 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void runCheckersForBranchCondition(const Stmt *condition, 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExplodedNodeSet &Dst, ExplodedNode *Pred, 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExprEngine &Eng); 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// \brief Run checkers for live symbols. 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// Allows modifying SymbolReaper object. For example, checkers can explicitly 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// register symbols of interest as live. These symbols will not be marked 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// dead and removed. 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void runCheckersForLiveSymbols(ProgramStateRef state, 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SymbolReaper &SymReaper); 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \brief Run checkers for dead symbols. 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// Notifies checkers when symbols become dead. For example, this allows 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// checkers to aggressively clean up/reduce the checker state and produce 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// precise diagnostics. 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ExplodedNodeSet &Src, 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SymbolReaper &SymReaper, const Stmt *S, 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ExprEngine &Eng, 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProgramPoint::Kind K); 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \brief True if at least one checker wants to check region changes. 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool wantsRegionChangeUpdate(ProgramStateRef state); 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \brief Run checkers for region changes. 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// This corresponds to the check::RegionChanges callback. 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \param state The current program state. 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \param invalidated A set of all symbols potentially touched by the change. 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \param ExplicitRegions The regions explicitly requested for invalidation. 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// For example, in the case of a function call, these would be arguments. 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \param Regions The transitive closure of accessible regions, 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// i.e. all regions that may have been touched by this change. 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \param Call The call expression wrapper if the regions are invalidated 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// by a call. 310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProgramStateRef 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) runCheckersForRegionChanges(ProgramStateRef state, 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const StoreManager::InvalidatedSymbols *invalidated, 313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ArrayRef<const MemRegion *> ExplicitRegions, 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ArrayRef<const MemRegion *> Regions, 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const CallEvent *Call); 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /// \brief Run checkers for handling assumptions on symbolic values. 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SVal Cond, bool Assumption); 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 321 /// \brief Run checkers for evaluating a call. 322 /// 323 /// Warning: Currently, the CallEvent MUST come from a CallExpr! 324 void runCheckersForEvalCall(ExplodedNodeSet &Dst, 325 const ExplodedNodeSet &Src, 326 const CallEvent &CE, ExprEngine &Eng); 327 328 /// \brief Run checkers for the entire Translation Unit. 329 void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, 330 AnalysisManager &mgr, 331 BugReporter &BR); 332 333 /// \brief Run checkers for debug-printing a ProgramState. 334 /// 335 /// Unlike most other callbacks, any checker can simply implement the virtual 336 /// method CheckerBase::printState if it has custom data to print. 337 /// \param Out The output stream 338 /// \param State The state being printed 339 /// \param NL The preferred representation of a newline. 340 /// \param Sep The preferred separator between different kinds of data. 341 void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State, 342 const char *NL, const char *Sep); 343 344//===----------------------------------------------------------------------===// 345// Internal registration functions for AST traversing. 346//===----------------------------------------------------------------------===// 347 348 // Functions used by the registration mechanism, checkers should not touch 349 // these directly. 350 351 typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)> 352 CheckDeclFunc; 353 354 typedef bool (*HandlesDeclFunc)(const Decl *D); 355 void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn); 356 357 void _registerForBody(CheckDeclFunc checkfn); 358 359//===----------------------------------------------------------------------===// 360// Internal registration functions for path-sensitive checking. 361//===----------------------------------------------------------------------===// 362 363 typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc; 364 365 typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)> 366 CheckObjCMessageFunc; 367 368 typedef CheckerFn<void (const CallEvent &, CheckerContext &)> 369 CheckCallFunc; 370 371 typedef CheckerFn<void (const SVal &location, bool isLoad, 372 const Stmt *S, 373 CheckerContext &)> 374 CheckLocationFunc; 375 376 typedef CheckerFn<void (const SVal &location, const SVal &val, 377 const Stmt *S, CheckerContext &)> 378 CheckBindFunc; 379 380 typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)> 381 CheckEndAnalysisFunc; 382 383 typedef CheckerFn<void (CheckerContext &)> 384 CheckEndPathFunc; 385 386 typedef CheckerFn<void (const Stmt *, CheckerContext &)> 387 CheckBranchConditionFunc; 388 389 typedef CheckerFn<void (SymbolReaper &, CheckerContext &)> 390 CheckDeadSymbolsFunc; 391 392 typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc; 393 394 typedef CheckerFn<ProgramStateRef (ProgramStateRef, 395 const StoreManager::InvalidatedSymbols *symbols, 396 ArrayRef<const MemRegion *> ExplicitRegions, 397 ArrayRef<const MemRegion *> Regions, 398 const CallEvent *Call)> 399 CheckRegionChangesFunc; 400 401 typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc; 402 403 typedef CheckerFn<ProgramStateRef (ProgramStateRef, 404 const SVal &cond, bool assumption)> 405 EvalAssumeFunc; 406 407 typedef CheckerFn<bool (const CallExpr *, CheckerContext &)> 408 EvalCallFunc; 409 410 typedef CheckerFn<bool (const CallExpr *, ExprEngine &Eng, 411 ExplodedNode *Pred, 412 ExplodedNodeSet &Dst)> 413 InlineCallFunc; 414 415 typedef CheckerFn<void (const TranslationUnitDecl *, 416 AnalysisManager&, BugReporter &)> 417 CheckEndOfTranslationUnit; 418 419 typedef bool (*HandlesStmtFunc)(const Stmt *D); 420 void _registerForPreStmt(CheckStmtFunc checkfn, 421 HandlesStmtFunc isForStmtFn); 422 void _registerForPostStmt(CheckStmtFunc checkfn, 423 HandlesStmtFunc isForStmtFn); 424 425 void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn); 426 void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn); 427 428 void _registerForPreCall(CheckCallFunc checkfn); 429 void _registerForPostCall(CheckCallFunc checkfn); 430 431 void _registerForLocation(CheckLocationFunc checkfn); 432 433 void _registerForBind(CheckBindFunc checkfn); 434 435 void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); 436 437 void _registerForEndPath(CheckEndPathFunc checkfn); 438 439 void _registerForBranchCondition(CheckBranchConditionFunc checkfn); 440 441 void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn); 442 443 void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn); 444 445 void _registerForRegionChanges(CheckRegionChangesFunc checkfn, 446 WantsRegionChangeUpdateFunc wantUpdateFn); 447 448 void _registerForEvalAssume(EvalAssumeFunc checkfn); 449 450 void _registerForEvalCall(EvalCallFunc checkfn); 451 452 void _registerForInlineCall(InlineCallFunc checkfn); 453 454 void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn); 455 456//===----------------------------------------------------------------------===// 457// Internal registration functions for events. 458//===----------------------------------------------------------------------===// 459 460 typedef void *EventTag; 461 typedef CheckerFn<void (const void *event)> CheckEventFunc; 462 463 template <typename EVENT> 464 void _registerListenerForEvent(CheckEventFunc checkfn) { 465 EventInfo &info = Events[getTag<EVENT>()]; 466 info.Checkers.push_back(checkfn); 467 } 468 469 template <typename EVENT> 470 void _registerDispatcherForEvent() { 471 EventInfo &info = Events[getTag<EVENT>()]; 472 info.HasDispatcher = true; 473 } 474 475 template <typename EVENT> 476 void _dispatchEvent(const EVENT &event) const { 477 EventsTy::const_iterator I = Events.find(getTag<EVENT>()); 478 if (I == Events.end()) 479 return; 480 const EventInfo &info = I->second; 481 for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i) 482 info.Checkers[i](&event); 483 } 484 485//===----------------------------------------------------------------------===// 486// Implementation details. 487//===----------------------------------------------------------------------===// 488 489private: 490 template <typename CHECKER> 491 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); } 492 493 template <typename T> 494 static void *getTag() { static int tag; return &tag; } 495 496 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags; 497 498 std::vector<CheckerDtor> CheckerDtors; 499 500 struct DeclCheckerInfo { 501 CheckDeclFunc CheckFn; 502 HandlesDeclFunc IsForDeclFn; 503 }; 504 std::vector<DeclCheckerInfo> DeclCheckers; 505 506 std::vector<CheckDeclFunc> BodyCheckers; 507 508 typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers; 509 typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy; 510 CachedDeclCheckersMapTy CachedDeclCheckersMap; 511 512 struct StmtCheckerInfo { 513 CheckStmtFunc CheckFn; 514 HandlesStmtFunc IsForStmtFn; 515 bool IsPreVisit; 516 }; 517 std::vector<StmtCheckerInfo> StmtCheckers; 518 519 struct CachedStmtCheckersKey { 520 unsigned StmtKind; 521 bool IsPreVisit; 522 523 CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { } 524 CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit) 525 : StmtKind(stmtKind), IsPreVisit(isPreVisit) { } 526 527 static CachedStmtCheckersKey getSentinel() { 528 return CachedStmtCheckersKey(~0U, 0); 529 } 530 unsigned getHashValue() const { 531 llvm::FoldingSetNodeID ID; 532 ID.AddInteger(StmtKind); 533 ID.AddBoolean(IsPreVisit); 534 return ID.ComputeHash(); 535 } 536 bool operator==(const CachedStmtCheckersKey &RHS) const { 537 return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit; 538 } 539 }; 540 friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>; 541 542 typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; 543 typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers> 544 CachedStmtCheckersMapTy; 545 CachedStmtCheckersMapTy CachedStmtCheckersMap; 546 547 CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit); 548 549 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; 550 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; 551 552 std::vector<CheckCallFunc> PreCallCheckers; 553 std::vector<CheckCallFunc> PostCallCheckers; 554 555 std::vector<CheckLocationFunc> LocationCheckers; 556 557 std::vector<CheckBindFunc> BindCheckers; 558 559 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers; 560 561 std::vector<CheckEndPathFunc> EndPathCheckers; 562 563 std::vector<CheckBranchConditionFunc> BranchConditionCheckers; 564 565 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers; 566 567 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers; 568 569 struct RegionChangesCheckerInfo { 570 CheckRegionChangesFunc CheckFn; 571 WantsRegionChangeUpdateFunc WantUpdateFn; 572 }; 573 std::vector<RegionChangesCheckerInfo> RegionChangesCheckers; 574 575 std::vector<EvalAssumeFunc> EvalAssumeCheckers; 576 577 std::vector<EvalCallFunc> EvalCallCheckers; 578 579 std::vector<InlineCallFunc> InlineCallCheckers; 580 581 std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers; 582 583 struct EventInfo { 584 SmallVector<CheckEventFunc, 4> Checkers; 585 bool HasDispatcher; 586 EventInfo() : HasDispatcher(false) { } 587 }; 588 589 typedef llvm::DenseMap<EventTag, EventInfo> EventsTy; 590 EventsTy Events; 591}; 592 593} // end ento namespace 594 595} // end clang namespace 596 597namespace llvm { 598 /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key 599 /// in DenseMap and DenseSets. 600 template <> 601 struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> { 602 static inline clang::ento::CheckerManager::CachedStmtCheckersKey 603 getEmptyKey() { 604 return clang::ento::CheckerManager::CachedStmtCheckersKey(); 605 } 606 static inline clang::ento::CheckerManager::CachedStmtCheckersKey 607 getTombstoneKey() { 608 return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel(); 609 } 610 611 static unsigned 612 getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) { 613 return S.getHashValue(); 614 } 615 616 static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS, 617 clang::ento::CheckerManager::CachedStmtCheckersKey RHS) { 618 return LHS == RHS; 619 } 620 }; 621} // end namespace llvm 622 623#endif 624