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