CheckerManager.h revision bf53dfac8195835028bd6347433f7dbebcc29fc1
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===// 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The LLVM Compiler Infrastructure 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// License. See LICENSE.TXT for details. 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Defines the Static Analyzer Checker Manager. 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch//===----------------------------------------------------------------------===// 132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H 152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H 162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "clang/Analysis/ProgramPoint.h" 182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "clang/Basic/LangOptions.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" 202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "llvm/ADT/DenseMap.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/ADT/FoldingSet.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/ADT/SmallVector.h" 232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include <vector> 242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace clang { 26a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch class Decl; 27a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch class Stmt; 28a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch class CallExpr; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace ento { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class CheckerBase; 32a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch class ExprEngine; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class AnalysisManager; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class BugReporter; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class CheckerContext; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class SimpleCall; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class ObjCMethodCall; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class SVal; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class ExplodedNode; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class ExplodedNodeSet; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class ExplodedGraph; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class ProgramState; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class NodeBuilder; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct NodeBuilderContext; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class MemRegion; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class SymbolReaper; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename T> class CheckerFn; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename RET, typename P1, typename P2, typename P3, typename P4, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typename P5> 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CheckerFn<RET(P1, P2, P3, P4, P5)> { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef RET (*Func)(void *, P1, P2, P3, P4, P5); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Func Fn; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerBase *Checker; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Fn(Checker, p1, p2, p3, p4, p5); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename RET, typename P1, typename P2, typename P3, typename P4> 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CheckerFn<RET(P1, P2, P3, P4)> { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef RET (*Func)(void *, P1, P2, P3, P4); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Func Fn; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerBase *Checker; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { 71a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return Fn(Checker, p1, p2, p3, p4); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 73a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75a3f7b4e666c476898878fa745f637129375cd889Ben Murdochtemplate <typename RET, typename P1, typename P2, typename P3> 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CheckerFn<RET(P1, P2, P3)> { 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef RET (*Func)(void *, P1, P2, P3); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Func Fn; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerBase *Checker; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename RET, typename P1, typename P2> 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CheckerFn<RET(P1, P2)> { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef RET (*Func)(void *, P1, P2); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Func Fn; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerBase *Checker; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename RET, typename P1> 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CheckerFn<RET(P1)> { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef RET (*Func)(void *, P1); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Func Fn; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerBase *Checker; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RET operator()(P1 p1) const { return Fn(Checker, p1); } 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename RET> 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CheckerFn<RET()> { 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef RET (*Func)(void *); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Func Fn; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerBase *Checker; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RET operator()() const { return Fn(Checker); } 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CheckerManager { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LangOptions LangOpts; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { } 120a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch ~CheckerManager(); 121a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 122a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch bool hasPathSensitiveCheckers() const; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void finishedCheckerRegistration(); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const LangOptions &getLangOpts() const { return LangOpts; } 127a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 128a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch typedef CheckerBase *CheckerRef; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef const void *CheckerTag; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void ()> CheckerDtor; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// registerChecker 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Used to register checkers. 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \returns a pointer to the checker object. 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename CHECKER> 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHECKER *registerChecker() { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerTag tag = getTag<CHECKER>(); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerRef &ref = CheckerTags[tag]; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ref) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return static_cast<CHECKER *>(ref); // already registered. 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECKER *checker = new CHECKER(); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>)); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECKER::_register(checker, *this); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref = checker; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return checker; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Functions for running checkers for AST traversing.. 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers handling Decls. 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, 159a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch BugReporter &BR); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers handling Decls containing a Stmt body. 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BugReporter &BR); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Functions for running checkers for path-sensitive checking. 16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)//===----------------------------------------------------------------------===// 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /// \brief Run checkers for pre-visiting Stmts. 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /// 17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /// The notification is performed for every explored CFGElement, which does 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /// not include the control flow statements such as IfStmt. 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /// 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /// \sa runCheckersForBranchCondition, runCheckersForPostStmt 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForPreStmt(ExplodedNodeSet &Dst, 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExplodedNodeSet &Src, 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const Stmt *S, 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExprEngine &Eng) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for post-visiting Stmts. 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// The notification is performed for every explored CFGElement, which does 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// not include the control flow statements such as IfStmt. 18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /// 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \sa runCheckersForBranchCondition, runCheckersForPreStmt 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForPostStmt(ExplodedNodeSet &Dst, 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExplodedNodeSet &Src, 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Stmt *S, 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExprEngine &Eng, 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool wasInlined = false) { 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for visiting Stmts. 1973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch void runCheckersForStmt(bool isPreVisit, 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Stmt *S, ExprEngine &Eng, 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool wasInlined = false); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for pre-visiting obj-c messages. 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, 20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ExplodedNodeSet &Src, 20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ObjCMethodCall &msg, 20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ExprEngine &Eng) { 20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for post-visiting obj-c messages. 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExplodedNodeSet &Src, 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjCMethodCall &msg, 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExprEngine &Eng, 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool wasInlined = false) { 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng, 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) wasInlined); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for visiting obj-c messages. 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForObjCMessage(bool isPreVisit, 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExplodedNodeSet &Dst, 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExplodedNodeSet &Src, 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjCMethodCall &msg, ExprEngine &Eng, 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool wasInlined = false); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for pre-visiting obj-c messages. 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CallEvent &Call, ExprEngine &Eng) { 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng); 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for post-visiting obj-c messages. 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CallEvent &Call, ExprEngine &Eng, 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool wasInlined = false) { 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng, 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) wasInlined); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for visiting obj-c messages. 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst, 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExplodedNodeSet &Src, 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CallEvent &Call, ExprEngine &Eng, 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool wasInlined = false); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for load/store of a location. 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForLocation(ExplodedNodeSet &Dst, 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExplodedNodeSet &Src, 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SVal location, 251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool isLoad, 252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const Stmt *NodeEx, 253a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const Stmt *BoundEx, 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExprEngine &Eng); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for binding of a value to a location. 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForBind(ExplodedNodeSet &Dst, 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExplodedNodeSet &Src, 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SVal location, SVal val, 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Stmt *S, ExprEngine &Eng, 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ProgramPoint &PP); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for end of analysis. 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExprEngine &Eng); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for end of path. 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForEndPath(NodeBuilderContext &BC, 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExplodedNodeSet &Dst, 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExplodedNode *Pred, 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExprEngine &Eng); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for branch condition. 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForBranchCondition(const Stmt *condition, 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExplodedNodeSet &Dst, ExplodedNode *Pred, 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExprEngine &Eng); 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for live symbols. 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// Allows modifying SymbolReaper object. For example, checkers can explicitly 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// register symbols of interest as live. These symbols will not be marked 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// dead and removed. 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForLiveSymbols(ProgramStateRef state, 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SymbolReaper &SymReaper); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for dead symbols. 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// Notifies checkers when symbols become dead. For example, this allows 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// checkers to aggressively clean up/reduce the checker state and produce 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// precise diagnostics. 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExplodedNodeSet &Src, 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SymbolReaper &SymReaper, const Stmt *S, 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExprEngine &Eng, 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProgramPoint::Kind K); 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief True if at least one checker wants to check region changes. 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool wantsRegionChangeUpdate(ProgramStateRef state); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for region changes. 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// This corresponds to the check::RegionChanges callback. 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \param state The current program state. 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// \param invalidated A set of all symbols potentially touched by the change. 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \param ExplicitRegions The regions explicitly requested for invalidation. 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// For example, in the case of a function call, these would be arguments. 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /// \param Regions The transitive closure of accessible regions, 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// i.e. all regions that may have been touched by this change. 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \param Call The call expression wrapper if the regions are invalidated 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// by a call. 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProgramStateRef 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) runCheckersForRegionChanges(ProgramStateRef state, 313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const InvalidatedSymbols *invalidated, 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ArrayRef<const MemRegion *> ExplicitRegions, 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ArrayRef<const MemRegion *> Regions, 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CallEvent *Call); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers when pointers escape. 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// This notifies the checkers about pointer escape, which occurs whenever 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// the analzyer cannot track the symbol any more. For example, as a 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /// result of assigning a pointer into a global or when it's passed to a 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /// function call the analyzer cannot model. 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /// 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /// \param State The state at the point of escape. 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /// \param Escaped The list of escaped symbols. 3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /// \param Call The corresponding CallEvent, if the symbols escape as 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// parameters to the given call. 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /// \returns Checkers can modify the state by returning a new one. 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const InvalidatedSymbols &Escaped, 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const CallEvent *Call); 3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /// \brief Run checkers for handling assumptions on symbolic values. 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, 3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SVal Cond, bool Assumption); 3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for evaluating a call. 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// Warning: Currently, the CallEvent MUST come from a CallExpr! 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForEvalCall(ExplodedNodeSet &Dst, 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExplodedNodeSet &Src, 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CallEvent &CE, ExprEngine &Eng); 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Run checkers for the entire Translation Unit. 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnalysisManager &mgr, 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BugReporter &BR); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /// \brief Run checkers for debug-printing a ProgramState. 35168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /// 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// Unlike most other callbacks, any checker can simply implement the virtual 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// method CheckerBase::printState if it has custom data to print. 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \param Out The output stream 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \param State The state being printed 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \param NL The preferred representation of a newline. 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \param Sep The preferred separator between different kinds of data. 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State, 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char *NL, const char *Sep); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Internal registration functions for AST traversing. 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Functions used by the registration mechanism, checkers should not touch 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // these directly. 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)> 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckDeclFunc; 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef bool (*HandlesDeclFunc)(const Decl *D); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForBody(CheckDeclFunc checkfn); 375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Internal registration functions for path-sensitive checking. 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc; 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)> 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckObjCMessageFunc; 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (const CallEvent &, CheckerContext &)> 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckCallFunc; 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (const SVal &location, bool isLoad, 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Stmt *S, 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckerContext &)> 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckLocationFunc; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (const SVal &location, const SVal &val, 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Stmt *S, CheckerContext &)> 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckBindFunc; 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)> 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckEndAnalysisFunc; 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (CheckerContext &)> 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckEndPathFunc; 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (const Stmt *, CheckerContext &)> 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckBranchConditionFunc; 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 406a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch typedef CheckerFn<void (SymbolReaper &, CheckerContext &)> 407a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch CheckDeadSymbolsFunc; 408a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 409a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc; 410a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 411a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch typedef CheckerFn<ProgramStateRef (ProgramStateRef, 412a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const InvalidatedSymbols *symbols, 413a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch ArrayRef<const MemRegion *> ExplicitRegions, 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ArrayRef<const MemRegion *> Regions, 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CallEvent *Call)> 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckRegionChangesFunc; 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc; 419a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<ProgramStateRef (ProgramStateRef, 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InvalidatedSymbols &Escaped, 42268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CallEvent *Call)> 42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CheckPointerEscapeFunc; 42468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 42568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) typedef CheckerFn<ProgramStateRef (ProgramStateRef, 42668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const SVal &cond, bool assumption)> 42768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EvalAssumeFunc; 42868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 42968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) typedef CheckerFn<bool (const CallExpr *, CheckerContext &)> 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EvalCallFunc; 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (const TranslationUnitDecl *, 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AnalysisManager&, BugReporter &)> 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckEndOfTranslationUnit; 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef bool (*HandlesStmtFunc)(const Stmt *D); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForPreStmt(CheckStmtFunc checkfn, 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HandlesStmtFunc isForStmtFn); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForPostStmt(CheckStmtFunc checkfn, 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HandlesStmtFunc isForStmtFn); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForPreCall(CheckCallFunc checkfn); 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForPostCall(CheckCallFunc checkfn); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForLocation(CheckLocationFunc checkfn); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForBind(CheckBindFunc checkfn); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForEndPath(CheckEndPathFunc checkfn); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForBranchCondition(CheckBranchConditionFunc checkfn); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn); 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForRegionChanges(CheckRegionChangesFunc checkfn, 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WantsRegionChangeUpdateFunc wantUpdateFn); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForPointerEscape(CheckPointerEscapeFunc checkfn); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForEvalAssume(EvalAssumeFunc checkfn); 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForEvalCall(EvalCallFunc checkfn); 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Internal registration functions for events. 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef void *EventTag; 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef CheckerFn<void (const void *event)> CheckEventFunc; 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename EVENT> 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerListenerForEvent(CheckEventFunc checkfn) { 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventInfo &info = Events[getTag<EVENT>()]; 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.Checkers.push_back(checkfn); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename EVENT> 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _registerDispatcherForEvent() { 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventInfo &info = Events[getTag<EVENT>()]; 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.HasDispatcher = true; 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename EVENT> 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void _dispatchEvent(const EVENT &event) const { 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventsTy::const_iterator I = Events.find(getTag<EVENT>()); 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (I == Events.end()) 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EventInfo &info = I->second; 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i) 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.Checkers[i](&event); 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Implementation details. 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)private: 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename CHECKER> 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); } 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void *getTag() { static int tag; return &tag; } 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<CheckerDtor> CheckerDtors; 516 517 struct DeclCheckerInfo { 518 CheckDeclFunc CheckFn; 519 HandlesDeclFunc IsForDeclFn; 520 }; 521 std::vector<DeclCheckerInfo> DeclCheckers; 522 523 std::vector<CheckDeclFunc> BodyCheckers; 524 525 typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers; 526 typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy; 527 CachedDeclCheckersMapTy CachedDeclCheckersMap; 528 529 struct StmtCheckerInfo { 530 CheckStmtFunc CheckFn; 531 HandlesStmtFunc IsForStmtFn; 532 bool IsPreVisit; 533 }; 534 std::vector<StmtCheckerInfo> StmtCheckers; 535 536 struct CachedStmtCheckersKey { 537 unsigned StmtKind; 538 bool IsPreVisit; 539 540 CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { } 541 CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit) 542 : StmtKind(stmtKind), IsPreVisit(isPreVisit) { } 543 544 static CachedStmtCheckersKey getSentinel() { 545 return CachedStmtCheckersKey(~0U, 0); 546 } 547 unsigned getHashValue() const { 548 llvm::FoldingSetNodeID ID; 549 ID.AddInteger(StmtKind); 550 ID.AddBoolean(IsPreVisit); 551 return ID.ComputeHash(); 552 } 553 bool operator==(const CachedStmtCheckersKey &RHS) const { 554 return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit; 555 } 556 }; 557 friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>; 558 559 typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; 560 typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers> 561 CachedStmtCheckersMapTy; 562 CachedStmtCheckersMapTy CachedStmtCheckersMap; 563 564 CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit); 565 566 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; 567 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; 568 569 std::vector<CheckCallFunc> PreCallCheckers; 570 std::vector<CheckCallFunc> PostCallCheckers; 571 572 std::vector<CheckLocationFunc> LocationCheckers; 573 574 std::vector<CheckBindFunc> BindCheckers; 575 576 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers; 577 578 std::vector<CheckEndPathFunc> EndPathCheckers; 579 580 std::vector<CheckBranchConditionFunc> BranchConditionCheckers; 581 582 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers; 583 584 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers; 585 586 struct RegionChangesCheckerInfo { 587 CheckRegionChangesFunc CheckFn; 588 WantsRegionChangeUpdateFunc WantUpdateFn; 589 }; 590 std::vector<RegionChangesCheckerInfo> RegionChangesCheckers; 591 592 std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers; 593 594 std::vector<EvalAssumeFunc> EvalAssumeCheckers; 595 596 std::vector<EvalCallFunc> EvalCallCheckers; 597 598 std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers; 599 600 struct EventInfo { 601 SmallVector<CheckEventFunc, 4> Checkers; 602 bool HasDispatcher; 603 EventInfo() : HasDispatcher(false) { } 604 }; 605 606 typedef llvm::DenseMap<EventTag, EventInfo> EventsTy; 607 EventsTy Events; 608}; 609 610} // end ento namespace 611 612} // end clang namespace 613 614namespace llvm { 615 /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key 616 /// in DenseMap and DenseSets. 617 template <> 618 struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> { 619 static inline clang::ento::CheckerManager::CachedStmtCheckersKey 620 getEmptyKey() { 621 return clang::ento::CheckerManager::CachedStmtCheckersKey(); 622 } 623 static inline clang::ento::CheckerManager::CachedStmtCheckersKey 624 getTombstoneKey() { 625 return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel(); 626 } 627 628 static unsigned 629 getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) { 630 return S.getHashValue(); 631 } 632 633 static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS, 634 clang::ento::CheckerManager::CachedStmtCheckersKey RHS) { 635 return LHS == RHS; 636 } 637 }; 638} // end namespace llvm 639 640#endif 641