CheckerManager.h revision 740d490593e0de8732a697c9f77b90ddd463863b
10a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===// 2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// 3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// The LLVM Compiler Infrastructure 4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// 5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// This file is distributed under the University of Illinois Open Source 6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// License. See LICENSE.TXT for details. 7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// 8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// 10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Defines the Static Analyzer Checker Manager. 11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// 12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H 15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H 16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "clang/Basic/LangOptions.h" 18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "llvm/ADT/SmallVector.h" 19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "llvm/ADT/DenseMap.h" 20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "llvm/ADT/FoldingSet.h" 21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" 22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "clang/Analysis/ProgramPoint.h" 23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include <vector> 24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace clang { 26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class Decl; 27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class Stmt; 28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class CallExpr; 29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace ento { 31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class CheckerBase; 32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class ExprEngine; 33a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class AnalysisManager; 34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class BugReporter; 35a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class CheckerContext; 36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class ObjCMessage; 37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class SVal; 38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class ExplodedNode; 39a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class ExplodedNodeSet; 40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class ExplodedGraph; 41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class ProgramState; 42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class NodeBuilder; 43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct NodeBuilderContext; 44a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class MemRegion; 45a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org class SymbolReaper; 46a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 47a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass GraphExpander { 48a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic: 49a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org virtual ~GraphExpander(); 50a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0; 51496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}; 52a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 53a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename T> class CheckerFn; 54a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 55a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename RET, typename P1, typename P2, typename P3, typename P4, 56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typename P5> 57496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgclass CheckerFn<RET(P1, P2, P3, P4, P5)> { 58a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef RET (*Func)(void *, P1, P2, P3, P4, P5); 59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Func Fn; 60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic: 61a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerBase *Checker; 62a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 63a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { 6431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return Fn(Checker, p1, p2, p3, p4, p5); 65a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 66a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}; 67a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename RET, typename P1, typename P2, typename P3, typename P4> 69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CheckerFn<RET(P1, P2, P3, P4)> { 70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef RET (*Func)(void *, P1, P2, P3, P4); 71a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Func Fn; 72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic: 73a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerBase *Checker; 74a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { 76a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return Fn(Checker, p1, p2, p3, p4); 77a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 78a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}; 79a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 80a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename RET, typename P1, typename P2, typename P3> 81a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CheckerFn<RET(P1, P2, P3)> { 82a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef RET (*Func)(void *, P1, P2, P3); 83a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Func Fn; 84a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic: 85a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerBase *Checker; 86a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 87a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } 88a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}; 89a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 90a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename RET, typename P1, typename P2> 91a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CheckerFn<RET(P1, P2)> { 92a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef RET (*Func)(void *, P1, P2); 93a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Func Fn; 94a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic: 95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerBase *Checker; 960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 97a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } 9883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org}; 99a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename RET, typename P1> 101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CheckerFn<RET(P1)> { 102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef RET (*Func)(void *, P1); 1039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org Func Fn; 104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic: 10549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org CheckerBase *Checker; 106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org RET operator()(P1 p1) const { return Fn(Checker, p1); } 108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}; 109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 110d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.orgtemplate <typename RET> 111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CheckerFn<RET()> { 1125f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org typedef RET (*Func)(void *); 113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Func Fn; 114d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.compublic: 115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerBase *Checker; 116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 1179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org RET operator()() const { return Fn(Checker); } 118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}; 119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 120c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgclass CheckerManager { 121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const LangOptions LangOpts; 122378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic: 124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { } 125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ~CheckerManager(); 126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool hasPathSensitiveCheckers() const; 128496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 129496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org void finishedCheckerRegistration(); 130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const LangOptions &getLangOpts() const { return LangOpts; } 132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerBase *CheckerRef; 13483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org typedef const void *CheckerTag; 135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void ()> CheckerDtor; 136496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 1375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org//===----------------------------------------------------------------------===// 138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// registerChecker 139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 140a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 141a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Used to register checkers. 142a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// 143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \returns a pointer to the checker object. 144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org template <typename CHECKER> 145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CHECKER *registerChecker() { 14683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org CheckerTag tag = getTag<CHECKER>(); 147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerRef &ref = CheckerTags[tag]; 148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (ref) 1493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return static_cast<CHECKER *>(ref); // already registered. 150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CHECKER *checker = new CHECKER(); 152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>)); 1530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org CHECKER::_register(checker, *this); 1540a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org ref = checker; 155a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return checker; 1560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 157a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 158a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 159a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Functions for running checkers for AST traversing.. 160a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers handling Decls. 163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, 164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org BugReporter &BR); 165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers handling Decls containing a Stmt body. 167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, 168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org BugReporter &BR); 169496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 170a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 171a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Functions for running checkers for path-sensitive checking. 172a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 17383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for pre-visiting Stmts. 175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// 176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// The notification is performed for every explored CFGElement, which does 177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// not include the control flow statements such as IfStmt. 178a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// 179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \sa runCheckersForBranchCondition, runCheckersForPostStmt 180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersForPreStmt(ExplodedNodeSet &Dst, 181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ExplodedNodeSet &Src, 182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const Stmt *S, 183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExprEngine &Eng) { 184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng); 185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for post-visiting Stmts. 188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// 189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// The notification is performed for every explored CFGElement, which does 190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// not include the control flow statements such as IfStmt. 191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// 192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \sa runCheckersForBranchCondition, runCheckersForPreStmt 1938f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org void runCheckersForPostStmt(ExplodedNodeSet &Dst, 1948f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org const ExplodedNodeSet &Src, 1958f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org const Stmt *S, 1968f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org ExprEngine &Eng, 1978f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org bool wasInlined = false) { 198a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined); 199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2008f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 2018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org /// \brief Run checkers for visiting Stmts. 2028f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org void runCheckersForStmt(bool isPreVisit, 2038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const Stmt *S, ExprEngine &Eng, 205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool wasInlined = false); 206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for pre-visiting obj-c messages. 208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, 209a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ExplodedNodeSet &Src, 210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ObjCMessage &msg, 211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExprEngine &Eng) { 212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng); 213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for post-visiting obj-c messages. 2168f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, 2178f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org const ExplodedNodeSet &Src, 2188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org const ObjCMessage &msg, 2198f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org ExprEngine &Eng) { 220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng); 2218f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 2228f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 2235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org /// \brief Run checkers for visiting obj-c messages. 224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersForObjCMessage(bool isPreVisit, 225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExplodedNodeSet &Dst, 226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ExplodedNodeSet &Src, 227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ObjCMessage &msg, ExprEngine &Eng); 228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2298f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org /// \brief Run checkers for load/store of a location. 2308f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org void runCheckersForLocation(ExplodedNodeSet &Dst, 231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ExplodedNodeSet &Src, 2328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org SVal location, 2338f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org bool isLoad, 2348f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org const Stmt *NodeEx, 235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const Stmt *BoundEx, 236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExprEngine &Eng); 237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for binding of a value to a location. 239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersForBind(ExplodedNodeSet &Dst, 240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ExplodedNodeSet &Src, 241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SVal location, SVal val, 242a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const Stmt *S, ExprEngine &Eng, 243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ProgramPoint::Kind PointKind); 244a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for end of analysis. 246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, 247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExprEngine &Eng); 248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for end of path. 250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersForEndPath(NodeBuilderContext &BC, 251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExplodedNodeSet &Dst, 252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExprEngine &Eng); 253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 254496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org /// \brief Run checkers for branch condition. 255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersForBranchCondition(const Stmt *condition, 256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExplodedNodeSet &Dst, ExplodedNode *Pred, 257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExprEngine &Eng); 258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for live symbols. 260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// 261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// Allows modifying SymbolReaper object. For example, checkers can explicitly 262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// register symbols of interest as live. These symbols will not be marked 263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// dead and removed. 264496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org void runCheckersForLiveSymbols(ProgramStateRef state, 265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SymbolReaper &SymReaper); 2663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for dead symbols. 268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// 269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// Notifies checkers when symbols become dead. For example, this allows 270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// checkers to aggressively clean up/reduce the checker state and produce 271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// precise diagnostics. 272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, 273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ExplodedNodeSet &Src, 274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SymbolReaper &SymReaper, const Stmt *S, 275496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org ExprEngine &Eng, 276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ProgramPoint::Kind K); 277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief True if at least one checker wants to check region changes. 279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool wantsRegionChangeUpdate(ProgramStateRef state); 280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for region changes. 282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// 283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// This corresponds to the check::RegionChanges callback. 284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \param state The current program state. 285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \param invalidated A set of all symbols potentially touched by the change. 286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \param ExplicitRegions The regions explicitly requested for invalidation. 287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// For example, in the case of a function call, these would be arguments. 288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \param Regions The transitive closure of accessible regions, 289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// i.e. all regions that may have been touched by this change. 290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \param Call The call expression wrapper if the regions are invalidated 291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// by a call. 292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ProgramStateRef 293a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org runCheckersForRegionChanges(ProgramStateRef state, 294a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const StoreManager::InvalidatedSymbols *invalidated, 295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ArrayRef<const MemRegion *> ExplicitRegions, 296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ArrayRef<const MemRegion *> Regions, 297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const CallEvent *Call); 298a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 299a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for handling assumptions on symbolic values. 300a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, 301a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SVal Cond, bool Assumption); 302a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for evaluating a call. 304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersForEvalCall(ExplodedNodeSet &Dst, 305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ExplodedNodeSet &Src, 306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const CallExpr *CE, ExprEngine &Eng, 307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org GraphExpander *defaultEval = 0); 308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for the entire Translation Unit. 310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, 311a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org AnalysisManager &mgr, 312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org BugReporter &BR); 313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \brief Run checkers for debug-printing a ProgramState. 315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// 316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// Unlike most other callbacks, any checker can simply implement the virtual 317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// method CheckerBase::printState if it has custom data to print. 318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \param Out The output stream 319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \param State The state being printed 320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \param NL The preferred representation of a newline. 321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// \param Sep The preferred separator between different kinds of data. 322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State, 323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const char *NL, const char *Sep); 324a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 325a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 326a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Internal registration functions for AST traversing. 327a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 329a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Functions used by the registration mechanism, checkers should not touch 330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // these directly. 331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)> 333a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckDeclFunc; 334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef bool (*HandlesDeclFunc)(const Decl *D); 336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn); 337a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForBody(CheckDeclFunc checkfn); 339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Internal registration functions for path-sensitive checking. 342a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc; 345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 346a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)> 347a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckObjCMessageFunc; 348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (const SVal &location, bool isLoad, 350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const Stmt *S, 351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckerContext &)> 352a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckLocationFunc; 353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (const SVal &location, const SVal &val, 355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const Stmt *S, CheckerContext &)> 356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckBindFunc; 357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)> 359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckEndAnalysisFunc; 360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 361a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (CheckerContext &)> 362a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckEndPathFunc; 363a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (const Stmt *, CheckerContext &)> 365a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckBranchConditionFunc; 366a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (SymbolReaper &, CheckerContext &)> 368a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckDeadSymbolsFunc; 369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc; 371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<ProgramStateRef (ProgramStateRef, 373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const StoreManager::InvalidatedSymbols *symbols, 374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ArrayRef<const MemRegion *> ExplicitRegions, 375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ArrayRef<const MemRegion *> Regions, 376a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const CallEvent *Call)> 377a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckRegionChangesFunc; 378a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 379a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc; 380a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<ProgramStateRef (ProgramStateRef, 382a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const SVal &cond, bool assumption)> 383a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EvalAssumeFunc; 384a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 385a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<bool (const CallExpr *, CheckerContext &)> 386a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EvalCallFunc; 387a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 388a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<bool (const CallExpr *, ExprEngine &Eng, 389a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExplodedNode *Pred, 390a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ExplodedNodeSet &Dst)> 391a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InlineCallFunc; 392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (const TranslationUnitDecl *, 394a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org AnalysisManager&, BugReporter &)> 395a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckEndOfTranslationUnit; 396a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 397a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef bool (*HandlesStmtFunc)(const Stmt *D); 398a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForPreStmt(CheckStmtFunc checkfn, 399a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HandlesStmtFunc isForStmtFn); 400a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForPostStmt(CheckStmtFunc checkfn, 401a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HandlesStmtFunc isForStmtFn); 402a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 403a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn); 404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn); 405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 406a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForLocation(CheckLocationFunc checkfn); 407a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 408a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForBind(CheckBindFunc checkfn); 409a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 410a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); 411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForEndPath(CheckEndPathFunc checkfn); 413a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForBranchCondition(CheckBranchConditionFunc checkfn); 415a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 416a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn); 417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 418a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn); 419a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 420a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForRegionChanges(CheckRegionChangesFunc checkfn, 421a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org WantsRegionChangeUpdateFunc wantUpdateFn); 422a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForEvalAssume(EvalAssumeFunc checkfn); 424a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 425a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForEvalCall(EvalCallFunc checkfn); 426a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 427a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForInlineCall(InlineCallFunc checkfn); 428a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn); 430a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 431a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 432a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Internal registration functions for events. 433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 434a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 435a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef void *EventTag; 436a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef CheckerFn<void (const void *event)> CheckEventFunc; 437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 438a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org template <typename EVENT> 439a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerListenerForEvent(CheckEventFunc checkfn) { 440a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EventInfo &info = Events[getTag<EVENT>()]; 441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org info.Checkers.push_back(checkfn); 442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org template <typename EVENT> 445a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _registerDispatcherForEvent() { 446a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EventInfo &info = Events[getTag<EVENT>()]; 447a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org info.HasDispatcher = true; 448a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 449a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 450a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org template <typename EVENT> 451a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void _dispatchEvent(const EVENT &event) const { 452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EventsTy::const_iterator I = Events.find(getTag<EVENT>()); 453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (I == Events.end()) 454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return; 455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const EventInfo &info = I->second; 456a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i) 457a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org info.Checkers[i](&event); 458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Implementation details. 462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===// 463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgprivate: 465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org template <typename CHECKER> 466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); } 467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org template <typename T> 469a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static void *getTag() { static int tag; return &tag; } 470a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 471a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags; 472a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 473a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<CheckerDtor> CheckerDtors; 474a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct DeclCheckerInfo { 476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckDeclFunc CheckFn; 477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HandlesDeclFunc IsForDeclFn; 478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 479a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<DeclCheckerInfo> DeclCheckers; 480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<CheckDeclFunc> BodyCheckers; 482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers; 484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy; 485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CachedDeclCheckersMapTy CachedDeclCheckersMap; 486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct StmtCheckerInfo { 488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckStmtFunc CheckFn; 489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HandlesStmtFunc IsForStmtFn; 490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool IsPreVisit; 491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<StmtCheckerInfo> StmtCheckers; 493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct CachedStmtCheckersKey { 495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org unsigned StmtKind; 496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool IsPreVisit; 497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { } 499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit) 500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org : StmtKind(stmtKind), IsPreVisit(isPreVisit) { } 5013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 5023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org static CachedStmtCheckersKey getSentinel() { 503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return CachedStmtCheckersKey(~0U, 0); 504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5053a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org unsigned getHashValue() const { 5063a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org llvm::FoldingSetNodeID ID; 507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ID.AddInteger(StmtKind); 508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ID.AddBoolean(IsPreVisit); 509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return ID.ComputeHash(); 510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 511a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool operator==(const CachedStmtCheckersKey &RHS) const { 512a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit; 513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>; 516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 517378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; 518378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers> 519378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org CachedStmtCheckersMapTy; 520378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org CachedStmtCheckersMapTy CachedStmtCheckersMap; 521378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 522378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit); 523378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; 525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; 526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<CheckLocationFunc> LocationCheckers; 528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<CheckBindFunc> BindCheckers; 530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers; 5323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 5333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org std::vector<CheckEndPathFunc> EndPathCheckers; 5343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<CheckBranchConditionFunc> BranchConditionCheckers; 536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers; 538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 539a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers; 540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct RegionChangesCheckerInfo { 542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CheckRegionChangesFunc CheckFn; 543a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org WantsRegionChangeUpdateFunc WantUpdateFn; 544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<RegionChangesCheckerInfo> RegionChangesCheckers; 546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 547a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<EvalAssumeFunc> EvalAssumeCheckers; 548a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org std::vector<EvalCallFunc> EvalCallCheckers; 5503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 551a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org std::vector<InlineCallFunc> InlineCallCheckers; 552a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers; 554a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 555a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct EventInfo { 556a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SmallVector<CheckEventFunc, 4> Checkers; 557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool HasDispatcher; 558a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EventInfo() : HasDispatcher(false) { } 559a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org typedef llvm::DenseMap<EventTag, EventInfo> EventsTy; 562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EventsTy Events; 563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}; 5643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} // end ento namespace 566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 567378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} // end clang namespace 568a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace llvm { 570a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key 571378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org /// in DenseMap and DenseSets. 572378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org template <> 5733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> { 574378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org static inline clang::ento::CheckerManager::CachedStmtCheckersKey 575378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org getEmptyKey() { 576378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org return clang::ento::CheckerManager::CachedStmtCheckersKey(); 577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static inline clang::ento::CheckerManager::CachedStmtCheckersKey 579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org getTombstoneKey() { 5803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel(); 581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 582a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static unsigned 584a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) { 585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return S.getHashValue(); 586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS, 589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org clang::ento::CheckerManager::CachedStmtCheckersKey RHS) { 590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return LHS == RHS; 591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org }; 593378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} // end namespace llvm 594378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 595378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org#endif 596378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org