Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- CheckerManager.cpp - Static Analyzer Checker Manager -------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// Defines the Static Analyzer Checker Manager.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
15
#include "clang/AST/DeclBase.h"
16
#include "clang/Analysis/ProgramPoint.h"
17
#include "clang/StaticAnalyzer/Core/Checker.h"
18
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
19
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
20
21
using namespace clang;
22
using namespace ento;
23
24
7.52k
bool CheckerManager::hasPathSensitiveCheckers() const {
25
7.52k
  return !StmtCheckers.empty()              ||
26
898
         !PreObjCMessageCheckers.empty()    ||
27
898
         !PostObjCMessageCheckers.empty()   ||
28
890
         !PreCallCheckers.empty()    ||
29
800
         !PostCallCheckers.empty()   ||
30
709
         !LocationCheckers.empty()          ||
31
687
         !BindCheckers.empty()              ||
32
687
         !EndAnalysisCheckers.empty()       ||
33
667
         !EndFunctionCheckers.empty()           ||
34
665
         !BranchConditionCheckers.empty()   ||
35
665
         !LiveSymbolsCheckers.empty()       ||
36
665
         !DeadSymbolsCheckers.empty()       ||
37
654
         !RegionChangesCheckers.empty()     ||
38
654
         !EvalAssumeCheckers.empty()        ||
39
654
         !EvalCallCheckers.empty();
40
7.52k
}
41
42
567
void CheckerManager::finishedCheckerRegistration() {
43
#ifndef NDEBUG
44
  // Make sure that for every event that has listeners, there is at least
45
  // one dispatcher registered for it.
46
  for (llvm::DenseMap<EventTag, EventInfo>::iterator
47
         I = Events.begin(), E = Events.end(); I != E; ++I)
48
    assert(I->second.HasDispatcher && "No dispatcher registered for an event");
49
#endif
50
}
51
52
//===----------------------------------------------------------------------===//
53
// Functions for running checkers for AST traversing..
54
//===----------------------------------------------------------------------===//
55
56
void CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
57
40.6k
                                          BugReporter &BR) {
58
40.6k
  assert(D);
59
40.6k
60
40.6k
  unsigned DeclKind = D->getKind();
61
40.6k
  CachedDeclCheckers *checkers = nullptr;
62
40.6k
  CachedDeclCheckersMapTy::iterator CCI = CachedDeclCheckersMap.find(DeclKind);
63
40.6k
  if (
CCI != CachedDeclCheckersMap.end()40.6k
) {
64
36.5k
    checkers = &(CCI->second);
65
40.6k
  } else {
66
4.11k
    // Find the checkers that should run for this Decl and cache them.
67
4.11k
    checkers = &CachedDeclCheckersMap[DeclKind];
68
4.85k
    for (unsigned i = 0, e = DeclCheckers.size(); 
i != e4.85k
;
++i739
) {
69
739
      DeclCheckerInfo &info = DeclCheckers[i];
70
739
      if (info.IsForDeclFn(D))
71
53
        checkers->push_back(info.CheckFn);
72
739
    }
73
4.11k
  }
74
40.6k
75
40.6k
  assert(checkers);
76
40.6k
  for (CachedDeclCheckers::iterator
77
41.0k
         I = checkers->begin(), E = checkers->end(); 
I != E41.0k
;
++I359
)
78
359
    (*I)(D, mgr, BR);
79
40.6k
}
80
81
void CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
82
8.48k
                                          BugReporter &BR) {
83
8.48k
  assert(D && D->hasBody());
84
8.48k
85
13.8k
  for (unsigned i = 0, e = BodyCheckers.size(); 
i != e13.8k
;
++i5.34k
)
86
5.34k
    BodyCheckers[i](D, mgr, BR);
87
8.48k
}
88
89
//===----------------------------------------------------------------------===//
90
// Functions for running checkers for path-sensitive checking.
91
//===----------------------------------------------------------------------===//
92
93
template <typename CHECK_CTX>
94
static void expandGraphWithCheckers(CHECK_CTX checkCtx,
95
                                    ExplodedNodeSet &Dst,
96
1.22M
                                    const ExplodedNodeSet &Src) {
97
1.22M
  const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
98
1.22M
  if (Src.empty())
99
13.0k
    return;
100
1.20M
101
1.20M
  typename CHECK_CTX::CheckersTy::const_iterator
102
1.20M
      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
103
1.20M
  if (
I == E1.20M
) {
104
305k
    Dst.insert(Src);
105
305k
    return;
106
305k
  }
107
902k
108
902k
  ExplodedNodeSet Tmp1, Tmp2;
109
902k
  const ExplodedNodeSet *PrevSet = &Src;
110
902k
111
2.43M
  for (; 
I != E2.43M
;
++I1.52M
) {
112
1.52M
    ExplodedNodeSet *CurrSet = nullptr;
113
1.52M
    if (I+1 == E)
114
902k
      CurrSet = &Dst;
115
627k
    else {
116
627k
      CurrSet = (PrevSet == &Tmp1) ? 
&Tmp2105k
:
&Tmp1521k
;
117
627k
      CurrSet->clear();
118
627k
    }
119
1.52M
120
1.52M
    NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
121
1.52M
    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
122
3.06M
         
NI != NE3.06M
;
++NI1.53M
) {
123
1.53M
      checkCtx.runChecker(*I, B, *NI);
124
1.53M
    }
125
1.52M
126
1.52M
    // If all the produced transitions are sinks, stop.
127
1.52M
    if (CurrSet->empty())
128
1.78k
      return;
129
1.52M
130
1.52M
    // Update which NodeSet is the current one.
131
1.52M
    PrevSet = CurrSet;
132
1.52M
  }
133
1.22M
}
CheckerManager.cpp:void expandGraphWithCheckers<(anonymous namespace)::CheckStmtContext>((anonymous namespace)::CheckStmtContext, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&)
Line
Count
Source
96
833k
                                    const ExplodedNodeSet &Src) {
97
833k
  const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
98
833k
  if (Src.empty())
99
6.41k
    return;
100
826k
101
826k
  typename CHECK_CTX::CheckersTy::const_iterator
102
826k
      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
103
826k
  if (
I == E826k
) {
104
285k
    Dst.insert(Src);
105
285k
    return;
106
285k
  }
107
541k
108
541k
  ExplodedNodeSet Tmp1, Tmp2;
109
541k
  const ExplodedNodeSet *PrevSet = &Src;
110
541k
111
1.32M
  for (; 
I != E1.32M
;
++I781k
) {
112
781k
    ExplodedNodeSet *CurrSet = nullptr;
113
781k
    if (I+1 == E)
114
541k
      CurrSet = &Dst;
115
240k
    else {
116
240k
      CurrSet = (PrevSet == &Tmp1) ? 
&Tmp218.7k
:
&Tmp1221k
;
117
240k
      CurrSet->clear();
118
240k
    }
119
781k
120
781k
    NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
121
781k
    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
122
1.56M
         
NI != NE1.56M
;
++NI781k
) {
123
781k
      checkCtx.runChecker(*I, B, *NI);
124
781k
    }
125
781k
126
781k
    // If all the produced transitions are sinks, stop.
127
781k
    if (CurrSet->empty())
128
550
      return;
129
781k
130
781k
    // Update which NodeSet is the current one.
131
781k
    PrevSet = CurrSet;
132
781k
  }
133
833k
}
CheckerManager.cpp:void expandGraphWithCheckers<(anonymous namespace)::CheckObjCMessageContext>((anonymous namespace)::CheckObjCMessageContext, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&)
Line
Count
Source
96
7.62k
                                    const ExplodedNodeSet &Src) {
97
7.62k
  const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
98
7.62k
  if (Src.empty())
99
568
    return;
100
7.05k
101
7.05k
  typename CHECK_CTX::CheckersTy::const_iterator
102
7.05k
      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
103
7.05k
  if (
I == E7.05k
) {
104
110
    Dst.insert(Src);
105
110
    return;
106
110
  }
107
6.94k
108
6.94k
  ExplodedNodeSet Tmp1, Tmp2;
109
6.94k
  const ExplodedNodeSet *PrevSet = &Src;
110
6.94k
111
22.3k
  for (; 
I != E22.3k
;
++I15.4k
) {
112
15.4k
    ExplodedNodeSet *CurrSet = nullptr;
113
15.4k
    if (I+1 == E)
114
6.93k
      CurrSet = &Dst;
115
8.54k
    else {
116
8.54k
      CurrSet = (PrevSet == &Tmp1) ? 
&Tmp22.52k
:
&Tmp16.01k
;
117
8.54k
      CurrSet->clear();
118
8.54k
    }
119
15.4k
120
15.4k
    NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
121
15.4k
    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
122
30.9k
         
NI != NE30.9k
;
++NI15.4k
) {
123
15.4k
      checkCtx.runChecker(*I, B, *NI);
124
15.4k
    }
125
15.4k
126
15.4k
    // If all the produced transitions are sinks, stop.
127
15.4k
    if (CurrSet->empty())
128
74
      return;
129
15.4k
130
15.4k
    // Update which NodeSet is the current one.
131
15.4k
    PrevSet = CurrSet;
132
15.4k
  }
133
7.62k
}
CheckerManager.cpp:void expandGraphWithCheckers<(anonymous namespace)::CheckCallContext>((anonymous namespace)::CheckCallContext, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&)
Line
Count
Source
96
110k
                                    const ExplodedNodeSet &Src) {
97
110k
  const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
98
110k
  if (Src.empty())
99
6.07k
    return;
100
104k
101
104k
  typename CHECK_CTX::CheckersTy::const_iterator
102
104k
      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
103
104k
  if (
I == E104k
) {
104
2.84k
    Dst.insert(Src);
105
2.84k
    return;
106
2.84k
  }
107
101k
108
101k
  ExplodedNodeSet Tmp1, Tmp2;
109
101k
  const ExplodedNodeSet *PrevSet = &Src;
110
101k
111
369k
  for (; 
I != E369k
;
++I268k
) {
112
268k
    ExplodedNodeSet *CurrSet = nullptr;
113
268k
    if (I+1 == E)
114
101k
      CurrSet = &Dst;
115
167k
    else {
116
167k
      CurrSet = (PrevSet == &Tmp1) ? 
&Tmp252.1k
:
&Tmp1115k
;
117
167k
      CurrSet->clear();
118
167k
    }
119
268k
120
268k
    NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
121
268k
    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
122
538k
         
NI != NE538k
;
++NI269k
) {
123
269k
      checkCtx.runChecker(*I, B, *NI);
124
269k
    }
125
268k
126
268k
    // If all the produced transitions are sinks, stop.
127
268k
    if (CurrSet->empty())
128
400
      return;
129
268k
130
268k
    // Update which NodeSet is the current one.
131
268k
    PrevSet = CurrSet;
132
268k
  }
133
110k
}
CheckerManager.cpp:void expandGraphWithCheckers<(anonymous namespace)::CheckLocationContext>((anonymous namespace)::CheckLocationContext, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&)
Line
Count
Source
96
122k
                                    const ExplodedNodeSet &Src) {
97
122k
  const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
98
122k
  if (Src.empty())
99
0
    return;
100
122k
101
122k
  typename CHECK_CTX::CheckersTy::const_iterator
102
122k
      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
103
122k
  if (
I == E122k
) {
104
3.47k
    Dst.insert(Src);
105
3.47k
    return;
106
3.47k
  }
107
118k
108
118k
  ExplodedNodeSet Tmp1, Tmp2;
109
118k
  const ExplodedNodeSet *PrevSet = &Src;
110
118k
111
288k
  for (; 
I != E288k
;
++I169k
) {
112
170k
    ExplodedNodeSet *CurrSet = nullptr;
113
170k
    if (I+1 == E)
114
118k
      CurrSet = &Dst;
115
51.4k
    else {
116
51.4k
      CurrSet = (PrevSet == &Tmp1) ? 
&Tmp2694
:
&Tmp150.7k
;
117
51.4k
      CurrSet->clear();
118
51.4k
    }
119
170k
120
170k
    NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
121
170k
    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
122
340k
         
NI != NE340k
;
++NI170k
) {
123
170k
      checkCtx.runChecker(*I, B, *NI);
124
170k
    }
125
170k
126
170k
    // If all the produced transitions are sinks, stop.
127
170k
    if (CurrSet->empty())
128
650
      return;
129
169k
130
169k
    // Update which NodeSet is the current one.
131
169k
    PrevSet = CurrSet;
132
169k
  }
133
122k
}
CheckerManager.cpp:void expandGraphWithCheckers<(anonymous namespace)::CheckBindContext>((anonymous namespace)::CheckBindContext, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&)
Line
Count
Source
96
48.3k
                                    const ExplodedNodeSet &Src) {
97
48.3k
  const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
98
48.3k
  if (Src.empty())
99
0
    return;
100
48.3k
101
48.3k
  typename CHECK_CTX::CheckersTy::const_iterator
102
48.3k
      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
103
48.3k
  if (
I == E48.3k
) {
104
1.99k
    Dst.insert(Src);
105
1.99k
    return;
106
1.99k
  }
107
46.4k
108
46.4k
  ExplodedNodeSet Tmp1, Tmp2;
109
46.4k
  const ExplodedNodeSet *PrevSet = &Src;
110
46.4k
111
143k
  for (; 
I != E143k
;
++I96.7k
) {
112
96.8k
    ExplodedNodeSet *CurrSet = nullptr;
113
96.8k
    if (I+1 == E)
114
46.3k
      CurrSet = &Dst;
115
50.4k
    else {
116
50.4k
      CurrSet = (PrevSet == &Tmp1) ? 
&Tmp23.68k
:
&Tmp146.7k
;
117
50.4k
      CurrSet->clear();
118
50.4k
    }
119
96.8k
120
96.8k
    NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
121
96.8k
    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
122
193k
         
NI != NE193k
;
++NI96.8k
) {
123
96.8k
      checkCtx.runChecker(*I, B, *NI);
124
96.8k
    }
125
96.8k
126
96.8k
    // If all the produced transitions are sinks, stop.
127
96.8k
    if (CurrSet->empty())
128
41
      return;
129
96.7k
130
96.7k
    // Update which NodeSet is the current one.
131
96.7k
    PrevSet = CurrSet;
132
96.7k
  }
133
48.3k
}
CheckerManager.cpp:void expandGraphWithCheckers<(anonymous namespace)::CheckBeginFunctionContext>((anonymous namespace)::CheckBeginFunctionContext, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&)
Line
Count
Source
96
11.8k
                                    const ExplodedNodeSet &Src) {
97
11.8k
  const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
98
11.8k
  if (Src.empty())
99
0
    return;
100
11.8k
101
11.8k
  typename CHECK_CTX::CheckersTy::const_iterator
102
11.8k
      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
103
11.8k
  if (
I == E11.8k
) {
104
9.74k
    Dst.insert(Src);
105
9.74k
    return;
106
9.74k
  }
107
2.13k
108
2.13k
  ExplodedNodeSet Tmp1, Tmp2;
109
2.13k
  const ExplodedNodeSet *PrevSet = &Src;
110
2.13k
111
4.58k
  for (; 
I != E4.58k
;
++I2.45k
) {
112
2.45k
    ExplodedNodeSet *CurrSet = nullptr;
113
2.45k
    if (I+1 == E)
114
2.13k
      CurrSet = &Dst;
115
318
    else {
116
318
      CurrSet = (PrevSet == &Tmp1) ? 
&Tmp21
:
&Tmp1317
;
117
318
      CurrSet->clear();
118
318
    }
119
2.45k
120
2.45k
    NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
121
2.45k
    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
122
4.90k
         
NI != NE4.90k
;
++NI2.45k
) {
123
2.45k
      checkCtx.runChecker(*I, B, *NI);
124
2.45k
    }
125
2.45k
126
2.45k
    // If all the produced transitions are sinks, stop.
127
2.45k
    if (CurrSet->empty())
128
0
      return;
129
2.45k
130
2.45k
    // Update which NodeSet is the current one.
131
2.45k
    PrevSet = CurrSet;
132
2.45k
  }
133
11.8k
}
CheckerManager.cpp:void expandGraphWithCheckers<(anonymous namespace)::CheckBranchConditionContext>((anonymous namespace)::CheckBranchConditionContext, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&)
Line
Count
Source
96
25.6k
                                    const ExplodedNodeSet &Src) {
97
25.6k
  const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
98
25.6k
  if (Src.empty())
99
0
    return;
100
25.6k
101
25.6k
  typename CHECK_CTX::CheckersTy::const_iterator
102
25.6k
      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
103
25.6k
  if (
I == E25.6k
) {
104
623
    Dst.insert(Src);
105
623
    return;
106
623
  }
107
24.9k
108
24.9k
  ExplodedNodeSet Tmp1, Tmp2;
109
24.9k
  const ExplodedNodeSet *PrevSet = &Src;
110
24.9k
111
51.1k
  for (; 
I != E51.1k
;
++I26.1k
) {
112
26.1k
    ExplodedNodeSet *CurrSet = nullptr;
113
26.1k
    if (I+1 == E)
114
24.9k
      CurrSet = &Dst;
115
1.18k
    else {
116
1.18k
      CurrSet = (PrevSet == &Tmp1) ? 
&Tmp20
:
&Tmp11.18k
;
117
1.18k
      CurrSet->clear();
118
1.18k
    }
119
26.1k
120
26.1k
    NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
121
26.1k
    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
122
52.3k
         
NI != NE52.3k
;
++NI26.1k
) {
123
26.1k
      checkCtx.runChecker(*I, B, *NI);
124
26.1k
    }
125
26.1k
126
26.1k
    // If all the produced transitions are sinks, stop.
127
26.1k
    if (CurrSet->empty())
128
50
      return;
129
26.1k
130
26.1k
    // Update which NodeSet is the current one.
131
26.1k
    PrevSet = CurrSet;
132
26.1k
  }
133
25.6k
}
CheckerManager.cpp:void expandGraphWithCheckers<(anonymous namespace)::CheckDeadSymbolsContext>((anonymous namespace)::CheckDeadSymbolsContext, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&)
Line
Count
Source
96
61.7k
                                    const ExplodedNodeSet &Src) {
97
61.7k
  const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
98
61.7k
  if (Src.empty())
99
0
    return;
100
61.7k
101
61.7k
  typename CHECK_CTX::CheckersTy::const_iterator
102
61.7k
      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
103
61.7k
  if (
I == E61.7k
) {
104
864
    Dst.insert(Src);
105
864
    return;
106
864
  }
107
60.8k
108
60.8k
  ExplodedNodeSet Tmp1, Tmp2;
109
60.8k
  const ExplodedNodeSet *PrevSet = &Src;
110
60.8k
111
228k
  for (; 
I != E228k
;
++I168k
) {
112
168k
    ExplodedNodeSet *CurrSet = nullptr;
113
168k
    if (I+1 == E)
114
60.8k
      CurrSet = &Dst;
115
107k
    else {
116
107k
      CurrSet = (PrevSet == &Tmp1) ? 
&Tmp227.8k
:
&Tmp179.4k
;
117
107k
      CurrSet->clear();
118
107k
    }
119
168k
120
168k
    NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
121
168k
    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
122
336k
         
NI != NE336k
;
++NI168k
) {
123
168k
      checkCtx.runChecker(*I, B, *NI);
124
168k
    }
125
168k
126
168k
    // If all the produced transitions are sinks, stop.
127
168k
    if (CurrSet->empty())
128
17
      return;
129
168k
130
168k
    // Update which NodeSet is the current one.
131
168k
    PrevSet = CurrSet;
132
168k
  }
133
61.7k
}
134
135
namespace {
136
  struct CheckStmtContext {
137
    typedef SmallVectorImpl<CheckerManager::CheckStmtFunc> CheckersTy;
138
    bool IsPreVisit;
139
    const CheckersTy &Checkers;
140
    const Stmt *S;
141
    ExprEngine &Eng;
142
    bool WasInlined;
143
144
826k
    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
145
826k
    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
146
147
    CheckStmtContext(bool isPreVisit, const CheckersTy &checkers,
148
                     const Stmt *s, ExprEngine &eng, bool wasInlined = false)
149
      : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng),
150
833k
        WasInlined(wasInlined) {}
151
152
    void runChecker(CheckerManager::CheckStmtFunc checkFn,
153
781k
                    NodeBuilder &Bldr, ExplodedNode *Pred) {
154
781k
      // FIXME: Remove respondsToCallback from CheckerContext;
155
347k
      ProgramPoint::Kind K =  IsPreVisit ? ProgramPoint::PreStmtKind :
156
434k
                                           ProgramPoint::PostStmtKind;
157
781k
      const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
158
781k
                                Pred->getLocationContext(), checkFn.Checker);
159
781k
      CheckerContext C(Bldr, Eng, Pred, L, WasInlined);
160
781k
      checkFn(S, C);
161
781k
    }
162
  };
163
}
164
165
/// \brief Run checkers for visiting Stmts.
166
void CheckerManager::runCheckersForStmt(bool isPreVisit,
167
                                        ExplodedNodeSet &Dst,
168
                                        const ExplodedNodeSet &Src,
169
                                        const Stmt *S,
170
                                        ExprEngine &Eng,
171
833k
                                        bool WasInlined) {
172
833k
  CheckStmtContext C(isPreVisit, getCachedStmtCheckersFor(S, isPreVisit),
173
833k
                     S, Eng, WasInlined);
174
833k
  expandGraphWithCheckers(C, Dst, Src);
175
833k
}
176
177
namespace {
178
  struct CheckObjCMessageContext {
179
    typedef std::vector<CheckerManager::CheckObjCMessageFunc> CheckersTy;
180
181
    ObjCMessageVisitKind Kind;
182
    bool WasInlined;
183
    const CheckersTy &Checkers;
184
    const ObjCMethodCall &Msg;
185
    ExprEngine &Eng;
186
187
7.05k
    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
188
7.05k
    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
189
190
    CheckObjCMessageContext(ObjCMessageVisitKind visitKind,
191
                            const CheckersTy &checkers,
192
                            const ObjCMethodCall &msg, ExprEngine &eng,
193
                            bool wasInlined)
194
      : Kind(visitKind), WasInlined(wasInlined), Checkers(checkers),
195
7.62k
        Msg(msg), Eng(eng) { }
196
197
    void runChecker(CheckerManager::CheckObjCMessageFunc checkFn,
198
15.4k
                    NodeBuilder &Bldr, ExplodedNode *Pred) {
199
15.4k
200
15.4k
      bool IsPreVisit;
201
15.4k
202
15.4k
      switch (Kind) {
203
8.23k
        case ObjCMessageVisitKind::Pre:
204
8.23k
          IsPreVisit = true;
205
8.23k
          break;
206
7.25k
        case ObjCMessageVisitKind::MessageNil:
207
7.25k
        case ObjCMessageVisitKind::Post:
208
7.25k
          IsPreVisit = false;
209
7.25k
          break;
210
15.4k
      }
211
15.4k
212
15.4k
      const ProgramPoint &L = Msg.getProgramPoint(IsPreVisit,checkFn.Checker);
213
15.4k
      CheckerContext C(Bldr, Eng, Pred, L, WasInlined);
214
15.4k
215
15.4k
      checkFn(*Msg.cloneWithState<ObjCMethodCall>(Pred->getState()), C);
216
15.4k
    }
217
  };
218
}
219
220
/// \brief Run checkers for visiting obj-c messages.
221
void CheckerManager::runCheckersForObjCMessage(ObjCMessageVisitKind visitKind,
222
                                               ExplodedNodeSet &Dst,
223
                                               const ExplodedNodeSet &Src,
224
                                               const ObjCMethodCall &msg,
225
                                               ExprEngine &Eng,
226
7.62k
                                               bool WasInlined) {
227
7.62k
  auto &checkers = getObjCMessageCheckers(visitKind);
228
7.62k
  CheckObjCMessageContext C(visitKind, checkers, msg, Eng, WasInlined);
229
7.62k
  expandGraphWithCheckers(C, Dst, Src);
230
7.62k
}
231
232
const std::vector<CheckerManager::CheckObjCMessageFunc> &
233
7.62k
CheckerManager::getObjCMessageCheckers(ObjCMessageVisitKind Kind) {
234
7.62k
  switch (Kind) {
235
3.52k
  case ObjCMessageVisitKind::Pre:
236
3.52k
    return PreObjCMessageCheckers;
237
0
    break;
238
4.00k
  case ObjCMessageVisitKind::Post:
239
4.00k
    return PostObjCMessageCheckers;
240
88
  case ObjCMessageVisitKind::MessageNil:
241
88
    return ObjCMessageNilCheckers;
242
0
  }
243
0
  
llvm_unreachable0
("Unknown Kind");
244
0
}
245
namespace {
246
  // FIXME: This has all the same signatures as CheckObjCMessageContext.
247
  // Is there a way we can merge the two?
248
  struct CheckCallContext {
249
    typedef std::vector<CheckerManager::CheckCallFunc> CheckersTy;
250
    bool IsPreVisit, WasInlined;
251
    const CheckersTy &Checkers;
252
    const CallEvent &Call;
253
    ExprEngine &Eng;
254
255
104k
    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
256
104k
    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
257
258
    CheckCallContext(bool isPreVisit, const CheckersTy &checkers,
259
                     const CallEvent &call, ExprEngine &eng,
260
                     bool wasInlined)
261
    : IsPreVisit(isPreVisit), WasInlined(wasInlined), Checkers(checkers),
262
110k
      Call(call), Eng(eng) { }
263
264
    void runChecker(CheckerManager::CheckCallFunc checkFn,
265
269k
                    NodeBuilder &Bldr, ExplodedNode *Pred) {
266
269k
      const ProgramPoint &L = Call.getProgramPoint(IsPreVisit,checkFn.Checker);
267
269k
      CheckerContext C(Bldr, Eng, Pred, L, WasInlined);
268
269k
269
269k
      checkFn(*Call.cloneWithState(Pred->getState()), C);
270
269k
    }
271
  };
272
}
273
274
/// \brief Run checkers for visiting an abstract call event.
275
void CheckerManager::runCheckersForCallEvent(bool isPreVisit,
276
                                             ExplodedNodeSet &Dst,
277
                                             const ExplodedNodeSet &Src,
278
                                             const CallEvent &Call,
279
                                             ExprEngine &Eng,
280
110k
                                             bool WasInlined) {
281
110k
  CheckCallContext C(isPreVisit,
282
52.2k
                     isPreVisit ? PreCallCheckers
283
58.0k
                                : PostCallCheckers,
284
110k
                     Call, Eng, WasInlined);
285
110k
  expandGraphWithCheckers(C, Dst, Src);
286
110k
}
287
288
namespace {
289
  struct CheckLocationContext {
290
    typedef std::vector<CheckerManager::CheckLocationFunc> CheckersTy;
291
    const CheckersTy &Checkers;
292
    SVal Loc;
293
    bool IsLoad;
294
    const Stmt *NodeEx; /* Will become a CFGStmt */
295
    const Stmt *BoundEx;
296
    ExprEngine &Eng;
297
298
122k
    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
299
122k
    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
300
301
    CheckLocationContext(const CheckersTy &checkers,
302
                         SVal loc, bool isLoad, const Stmt *NodeEx,
303
                         const Stmt *BoundEx,
304
                         ExprEngine &eng)
305
      : Checkers(checkers), Loc(loc), IsLoad(isLoad), NodeEx(NodeEx),
306
122k
        BoundEx(BoundEx), Eng(eng) {}
307
308
    void runChecker(CheckerManager::CheckLocationFunc checkFn,
309
170k
                    NodeBuilder &Bldr, ExplodedNode *Pred) {
310
134k
      ProgramPoint::Kind K =  IsLoad ? ProgramPoint::PreLoadKind :
311
35.3k
                                       ProgramPoint::PreStoreKind;
312
170k
      const ProgramPoint &L =
313
170k
        ProgramPoint::getProgramPoint(NodeEx, K,
314
170k
                                      Pred->getLocationContext(),
315
170k
                                      checkFn.Checker);
316
170k
      CheckerContext C(Bldr, Eng, Pred, L);
317
170k
      checkFn(Loc, IsLoad, BoundEx, C);
318
170k
    }
319
  };
320
}
321
322
/// \brief Run checkers for load/store of a location.
323
324
void CheckerManager::runCheckersForLocation(ExplodedNodeSet &Dst,
325
                                            const ExplodedNodeSet &Src,
326
                                            SVal location, bool isLoad,
327
                                            const Stmt *NodeEx,
328
                                            const Stmt *BoundEx,
329
122k
                                            ExprEngine &Eng) {
330
122k
  CheckLocationContext C(LocationCheckers, location, isLoad, NodeEx,
331
122k
                         BoundEx, Eng);
332
122k
  expandGraphWithCheckers(C, Dst, Src);
333
122k
}
334
335
namespace {
336
  struct CheckBindContext {
337
    typedef std::vector<CheckerManager::CheckBindFunc> CheckersTy;
338
    const CheckersTy &Checkers;
339
    SVal Loc;
340
    SVal Val;
341
    const Stmt *S;
342
    ExprEngine &Eng;
343
    const ProgramPoint &PP;
344
345
48.3k
    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
346
48.3k
    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
347
348
    CheckBindContext(const CheckersTy &checkers,
349
                     SVal loc, SVal val, const Stmt *s, ExprEngine &eng,
350
                     const ProgramPoint &pp)
351
48.3k
      : Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng), PP(pp) {}
352
353
    void runChecker(CheckerManager::CheckBindFunc checkFn,
354
96.8k
                    NodeBuilder &Bldr, ExplodedNode *Pred) {
355
96.8k
      const ProgramPoint &L = PP.withTag(checkFn.Checker);
356
96.8k
      CheckerContext C(Bldr, Eng, Pred, L);
357
96.8k
358
96.8k
      checkFn(Loc, Val, S, C);
359
96.8k
    }
360
  };
361
}
362
363
/// \brief Run checkers for binding of a value to a location.
364
void CheckerManager::runCheckersForBind(ExplodedNodeSet &Dst,
365
                                        const ExplodedNodeSet &Src,
366
                                        SVal location, SVal val,
367
                                        const Stmt *S, ExprEngine &Eng,
368
48.3k
                                        const ProgramPoint &PP) {
369
48.3k
  CheckBindContext C(BindCheckers, location, val, S, Eng, PP);
370
48.3k
  expandGraphWithCheckers(C, Dst, Src);
371
48.3k
}
372
373
void CheckerManager::runCheckersForEndAnalysis(ExplodedGraph &G,
374
                                               BugReporter &BR,
375
6.87k
                                               ExprEngine &Eng) {
376
10.9k
  for (unsigned i = 0, e = EndAnalysisCheckers.size(); 
i != e10.9k
;
++i4.03k
)
377
4.03k
    EndAnalysisCheckers[i](G, BR, Eng);
378
6.87k
}
379
380
namespace {
381
struct CheckBeginFunctionContext {
382
  typedef std::vector<CheckerManager::CheckBeginFunctionFunc> CheckersTy;
383
  const CheckersTy &Checkers;
384
  ExprEngine &Eng;
385
  const ProgramPoint &PP;
386
387
11.8k
  CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
388
11.8k
  CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
389
390
  CheckBeginFunctionContext(const CheckersTy &Checkers, ExprEngine &Eng,
391
                            const ProgramPoint &PP)
392
11.8k
      : Checkers(Checkers), Eng(Eng), PP(PP) {}
393
394
  void runChecker(CheckerManager::CheckBeginFunctionFunc checkFn,
395
2.45k
                  NodeBuilder &Bldr, ExplodedNode *Pred) {
396
2.45k
    const ProgramPoint &L = PP.withTag(checkFn.Checker);
397
2.45k
    CheckerContext C(Bldr, Eng, Pred, L);
398
2.45k
399
2.45k
    checkFn(C);
400
2.45k
  }
401
};
402
}
403
404
void CheckerManager::runCheckersForBeginFunction(ExplodedNodeSet &Dst,
405
                                                 const BlockEdge &L,
406
                                                 ExplodedNode *Pred,
407
11.8k
                                                 ExprEngine &Eng) {
408
11.8k
  ExplodedNodeSet Src;
409
11.8k
  Src.insert(Pred);
410
11.8k
  CheckBeginFunctionContext C(BeginFunctionCheckers, Eng, L);
411
11.8k
  expandGraphWithCheckers(C, Dst, Src);
412
11.8k
}
413
414
/// \brief Run checkers for end of path.
415
// Note, We do not chain the checker output (like in expandGraphWithCheckers)
416
// for this callback since end of path nodes are expected to be final.
417
void CheckerManager::runCheckersForEndFunction(NodeBuilderContext &BC,
418
                                               ExplodedNodeSet &Dst,
419
                                               ExplodedNode *Pred,
420
13.1k
                                               ExprEngine &Eng) {
421
13.1k
422
13.1k
  // We define the builder outside of the loop bacause if at least one checkers
423
13.1k
  // creates a sucsessor for Pred, we do not need to generate an
424
13.1k
  // autotransition for it.
425
13.1k
  NodeBuilder Bldr(Pred, Dst, BC);
426
28.8k
  for (unsigned i = 0, e = EndFunctionCheckers.size(); 
i != e28.8k
;
++i15.6k
) {
427
15.6k
    CheckEndFunctionFunc checkFn = EndFunctionCheckers[i];
428
15.6k
429
15.6k
    const ProgramPoint &L = BlockEntrance(BC.Block,
430
15.6k
                                          Pred->getLocationContext(),
431
15.6k
                                          checkFn.Checker);
432
15.6k
    CheckerContext C(Bldr, Eng, Pred, L);
433
15.6k
    checkFn(C);
434
15.6k
  }
435
13.1k
}
436
437
namespace {
438
  struct CheckBranchConditionContext {
439
    typedef std::vector<CheckerManager::CheckBranchConditionFunc> CheckersTy;
440
    const CheckersTy &Checkers;
441
    const Stmt *Condition;
442
    ExprEngine &Eng;
443
444
25.6k
    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
445
25.6k
    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
446
447
    CheckBranchConditionContext(const CheckersTy &checkers,
448
                                const Stmt *Cond, ExprEngine &eng)
449
25.6k
      : Checkers(checkers), Condition(Cond), Eng(eng) {}
450
451
    void runChecker(CheckerManager::CheckBranchConditionFunc checkFn,
452
26.1k
                    NodeBuilder &Bldr, ExplodedNode *Pred) {
453
26.1k
      ProgramPoint L = PostCondition(Condition, Pred->getLocationContext(),
454
26.1k
                                     checkFn.Checker);
455
26.1k
      CheckerContext C(Bldr, Eng, Pred, L);
456
26.1k
      checkFn(Condition, C);
457
26.1k
    }
458
  };
459
}
460
461
/// \brief Run checkers for branch condition.
462
void CheckerManager::runCheckersForBranchCondition(const Stmt *Condition,
463
                                                   ExplodedNodeSet &Dst,
464
                                                   ExplodedNode *Pred,
465
25.6k
                                                   ExprEngine &Eng) {
466
25.6k
  ExplodedNodeSet Src;
467
25.6k
  Src.insert(Pred);
468
25.6k
  CheckBranchConditionContext C(BranchConditionCheckers, Condition, Eng);
469
25.6k
  expandGraphWithCheckers(C, Dst, Src);
470
25.6k
}
471
472
/// \brief Run checkers for live symbols.
473
void CheckerManager::runCheckersForLiveSymbols(ProgramStateRef state,
474
179k
                                               SymbolReaper &SymReaper) {
475
244k
  for (unsigned i = 0, e = LiveSymbolsCheckers.size(); 
i != e244k
;
++i64.5k
)
476
64.5k
    LiveSymbolsCheckers[i](state, SymReaper);
477
179k
}
478
479
namespace {
480
  struct CheckDeadSymbolsContext {
481
    typedef std::vector<CheckerManager::CheckDeadSymbolsFunc> CheckersTy;
482
    const CheckersTy &Checkers;
483
    SymbolReaper &SR;
484
    const Stmt *S;
485
    ExprEngine &Eng;
486
    ProgramPoint::Kind ProgarmPointKind;
487
488
61.7k
    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
489
61.7k
    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
490
491
    CheckDeadSymbolsContext(const CheckersTy &checkers, SymbolReaper &sr,
492
                            const Stmt *s, ExprEngine &eng,
493
                            ProgramPoint::Kind K)
494
61.7k
      : Checkers(checkers), SR(sr), S(s), Eng(eng), ProgarmPointKind(K) { }
495
496
    void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn,
497
168k
                    NodeBuilder &Bldr, ExplodedNode *Pred) {
498
168k
      const ProgramPoint &L = ProgramPoint::getProgramPoint(S, ProgarmPointKind,
499
168k
                                Pred->getLocationContext(), checkFn.Checker);
500
168k
      CheckerContext C(Bldr, Eng, Pred, L);
501
168k
502
168k
      // Note, do not pass the statement to the checkers without letting them
503
168k
      // differentiate if we ran remove dead bindings before or after the
504
168k
      // statement.
505
168k
      checkFn(SR, C);
506
168k
    }
507
  };
508
}
509
510
/// \brief Run checkers for dead symbols.
511
void CheckerManager::runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
512
                                               const ExplodedNodeSet &Src,
513
                                               SymbolReaper &SymReaper,
514
                                               const Stmt *S,
515
                                               ExprEngine &Eng,
516
61.7k
                                               ProgramPoint::Kind K) {
517
61.7k
  CheckDeadSymbolsContext C(DeadSymbolsCheckers, SymReaper, S, Eng, K);
518
61.7k
  expandGraphWithCheckers(C, Dst, Src);
519
61.7k
}
520
521
/// \brief Run checkers for region changes.
522
ProgramStateRef
523
CheckerManager::runCheckersForRegionChanges(ProgramStateRef state,
524
                                            const InvalidatedSymbols *invalidated,
525
                                            ArrayRef<const MemRegion *> ExplicitRegions,
526
                                            ArrayRef<const MemRegion *> Regions,
527
                                            const LocationContext *LCtx,
528
99.9k
                                            const CallEvent *Call) {
529
147k
  for (unsigned i = 0, e = RegionChangesCheckers.size(); 
i != e147k
;
++i47.3k
) {
530
47.3k
    // If any checker declares the state infeasible (or if it starts that way),
531
47.3k
    // bail out.
532
47.3k
    if (!state)
533
0
      return nullptr;
534
47.3k
    state = RegionChangesCheckers[i](state, invalidated,
535
47.3k
                                     ExplicitRegions, Regions,
536
47.3k
                                     LCtx, Call);
537
47.3k
  }
538
99.9k
  return state;
539
99.9k
}
540
541
/// \brief Run checkers to process symbol escape event.
542
ProgramStateRef
543
CheckerManager::runCheckersForPointerEscape(ProgramStateRef State,
544
                                   const InvalidatedSymbols &Escaped,
545
                                   const CallEvent *Call,
546
                                   PointerEscapeKind Kind,
547
28.0k
                                   RegionAndSymbolInvalidationTraits *ETraits) {
548
28.0k
  assert((Call != nullptr ||
549
28.0k
          (Kind != PSK_DirectEscapeOnCall &&
550
28.0k
           Kind != PSK_IndirectEscapeOnCall)) &&
551
28.0k
         "Call must not be NULL when escaping on call");
552
49.2k
    for (unsigned i = 0, e = PointerEscapeCheckers.size(); 
i != e49.2k
;
++i21.1k
) {
553
21.1k
      // If any checker declares the state infeasible (or if it starts that
554
21.1k
      //  way), bail out.
555
21.1k
      if (!State)
556
0
        return nullptr;
557
21.1k
      State = PointerEscapeCheckers[i](State, Escaped, Call, Kind, ETraits);
558
21.1k
    }
559
28.0k
  return State;
560
28.0k
}
561
562
/// \brief Run checkers for handling assumptions on symbolic values.
563
ProgramStateRef
564
CheckerManager::runCheckersForEvalAssume(ProgramStateRef state,
565
402k
                                         SVal Cond, bool Assumption) {
566
509k
  for (unsigned i = 0, e = EvalAssumeCheckers.size(); 
i != e509k
;
++i106k
) {
567
173k
    // If any checker declares the state infeasible (or if it starts that way),
568
173k
    // bail out.
569
173k
    if (!state)
570
66.8k
      return nullptr;
571
106k
    state = EvalAssumeCheckers[i](state, Cond, Assumption);
572
106k
  }
573
335k
  return state;
574
402k
}
575
576
/// \brief Run checkers for evaluating a call.
577
/// Only one checker will evaluate the call.
578
void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst,
579
                                            const ExplodedNodeSet &Src,
580
                                            const CallEvent &Call,
581
30.9k
                                            ExprEngine &Eng) {
582
30.9k
  const CallExpr *CE = cast<CallExpr>(Call.getOriginExpr());
583
30.9k
  for (ExplodedNodeSet::iterator
584
61.7k
         NI = Src.begin(), NE = Src.end(); 
NI != NE61.7k
;
++NI30.7k
) {
585
30.7k
    ExplodedNode *Pred = *NI;
586
30.7k
    bool anyEvaluated = false;
587
30.7k
588
30.7k
    ExplodedNodeSet checkDst;
589
30.7k
    NodeBuilder B(Pred, checkDst, Eng.getBuilderContext());
590
30.7k
591
30.7k
    // Check if any of the EvalCall callbacks can evaluate the call.
592
30.7k
    for (std::vector<EvalCallFunc>::iterator
593
30.7k
           EI = EvalCallCheckers.begin(), EE = EvalCallCheckers.end();
594
73.9k
         
EI != EE73.9k
;
++EI43.1k
) {
595
49.0k
      ProgramPoint::Kind K = ProgramPoint::PostStmtKind;
596
49.0k
      const ProgramPoint &L = ProgramPoint::getProgramPoint(CE, K,
597
49.0k
                                Pred->getLocationContext(), EI->Checker);
598
49.0k
      bool evaluated = false;
599
49.0k
      { // CheckerContext generates transitions(populates checkDest) on
600
49.0k
        // destruction, so introduce the scope to make sure it gets properly
601
49.0k
        // populated.
602
49.0k
        CheckerContext C(B, Eng, Pred, L);
603
49.0k
        evaluated = (*EI)(CE, C);
604
49.0k
      }
605
49.0k
      assert(!(evaluated && anyEvaluated)
606
49.0k
             && "There are more than one checkers evaluating the call");
607
49.0k
      if (
evaluated49.0k
) {
608
5.92k
        anyEvaluated = true;
609
5.92k
        Dst.insert(checkDst);
610
5.92k
#ifdef NDEBUG
611
5.92k
        break; // on release don't check that no other checker also evals.
612
5.92k
#endif
613
5.92k
      }
614
49.0k
    }
615
30.7k
616
30.7k
    // If none of the checkers evaluated the call, ask ExprEngine to handle it.
617
30.7k
    if (
!anyEvaluated30.7k
) {
618
24.8k
      NodeBuilder B(Pred, Dst, Eng.getBuilderContext());
619
24.8k
      Eng.defaultEvalCall(B, Pred, Call);
620
24.8k
    }
621
30.7k
  }
622
30.9k
}
623
624
/// \brief Run checkers for the entire Translation Unit.
625
void CheckerManager::runCheckersOnEndOfTranslationUnit(
626
                                                  const TranslationUnitDecl *TU,
627
                                                  AnalysisManager &mgr,
628
555
                                                  BugReporter &BR) {
629
584
  for (unsigned i = 0, e = EndOfTranslationUnitCheckers.size(); 
i != e584
;
++i29
)
630
29
    EndOfTranslationUnitCheckers[i](TU, mgr, BR);
631
555
}
632
633
void CheckerManager::runCheckersForPrintState(raw_ostream &Out,
634
                                              ProgramStateRef State,
635
1
                                              const char *NL, const char *Sep) {
636
1
  for (llvm::DenseMap<CheckerTag, CheckerRef>::iterator
637
2
        I = CheckerTags.begin(), E = CheckerTags.end(); 
I != E2
;
++I1
)
638
1
    I->second->printState(Out, State, NL, Sep);
639
1
}
640
641
//===----------------------------------------------------------------------===//
642
// Internal registration functions for AST traversing.
643
//===----------------------------------------------------------------------===//
644
645
void CheckerManager::_registerForDecl(CheckDeclFunc checkfn,
646
101
                                      HandlesDeclFunc isForDeclFn) {
647
101
  DeclCheckerInfo info = { checkfn, isForDeclFn };
648
101
  DeclCheckers.push_back(info);
649
101
}
650
651
358
void CheckerManager::_registerForBody(CheckDeclFunc checkfn) {
652
358
  BodyCheckers.push_back(checkfn);
653
358
}
654
655
//===----------------------------------------------------------------------===//
656
// Internal registration functions for path-sensitive checking.
657
//===----------------------------------------------------------------------===//
658
659
void CheckerManager::_registerForPreStmt(CheckStmtFunc checkfn,
660
4.04k
                                         HandlesStmtFunc isForStmtFn) {
661
4.04k
  StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/true };
662
4.04k
  StmtCheckers.push_back(info);
663
4.04k
}
664
void CheckerManager::_registerForPostStmt(CheckStmtFunc checkfn,
665
2.75k
                                          HandlesStmtFunc isForStmtFn) {
666
2.75k
  StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/false };
667
2.75k
  StmtCheckers.push_back(info);
668
2.75k
}
669
670
920
void CheckerManager::_registerForPreObjCMessage(CheckObjCMessageFunc checkfn) {
671
920
  PreObjCMessageCheckers.push_back(checkfn);
672
920
}
673
674
415
void CheckerManager::_registerForObjCMessageNil(CheckObjCMessageFunc checkfn) {
675
415
  ObjCMessageNilCheckers.push_back(checkfn);
676
415
}
677
678
1.01k
void CheckerManager::_registerForPostObjCMessage(CheckObjCMessageFunc checkfn) {
679
1.01k
  PostObjCMessageCheckers.push_back(checkfn);
680
1.01k
}
681
682
1.43k
void CheckerManager::_registerForPreCall(CheckCallFunc checkfn) {
683
1.43k
  PreCallCheckers.push_back(checkfn);
684
1.43k
}
685
984
void CheckerManager::_registerForPostCall(CheckCallFunc checkfn) {
686
984
  PostCallCheckers.push_back(checkfn);
687
984
}
688
689
568
void CheckerManager::_registerForLocation(CheckLocationFunc checkfn) {
690
568
  LocationCheckers.push_back(checkfn);
691
568
}
692
693
1.01k
void CheckerManager::_registerForBind(CheckBindFunc checkfn) {
694
1.01k
  BindCheckers.push_back(checkfn);
695
1.01k
}
696
697
203
void CheckerManager::_registerForEndAnalysis(CheckEndAnalysisFunc checkfn) {
698
203
  EndAnalysisCheckers.push_back(checkfn);
699
203
}
700
701
91
void CheckerManager::_registerForBeginFunction(CheckBeginFunctionFunc checkfn) {
702
91
  BeginFunctionCheckers.push_back(checkfn);
703
91
}
704
705
568
void CheckerManager::_registerForEndFunction(CheckEndFunctionFunc checkfn) {
706
568
  EndFunctionCheckers.push_back(checkfn);
707
568
}
708
709
void CheckerManager::_registerForBranchCondition(
710
487
                                             CheckBranchConditionFunc checkfn) {
711
487
  BranchConditionCheckers.push_back(checkfn);
712
487
}
713
714
106
void CheckerManager::_registerForLiveSymbols(CheckLiveSymbolsFunc checkfn) {
715
106
  LiveSymbolsCheckers.push_back(checkfn);
716
106
}
717
718
937
void CheckerManager::_registerForDeadSymbols(CheckDeadSymbolsFunc checkfn) {
719
937
  DeadSymbolsCheckers.push_back(checkfn);
720
937
}
721
722
170
void CheckerManager::_registerForRegionChanges(CheckRegionChangesFunc checkfn) {
723
170
  RegionChangesCheckers.push_back(checkfn);
724
170
}
725
726
228
void CheckerManager::_registerForPointerEscape(CheckPointerEscapeFunc checkfn){
727
228
  PointerEscapeCheckers.push_back(checkfn);
728
228
}
729
730
void CheckerManager::_registerForConstPointerEscape(
731
0
                                          CheckPointerEscapeFunc checkfn) {
732
0
  PointerEscapeCheckers.push_back(checkfn);
733
0
}
734
735
183
void CheckerManager::_registerForEvalAssume(EvalAssumeFunc checkfn) {
736
183
  EvalAssumeCheckers.push_back(checkfn);
737
183
}
738
739
754
void CheckerManager::_registerForEvalCall(EvalCallFunc checkfn) {
740
754
  EvalCallCheckers.push_back(checkfn);
741
754
}
742
743
void CheckerManager::_registerForEndOfTranslationUnit(
744
29
                                            CheckEndOfTranslationUnit checkfn) {
745
29
  EndOfTranslationUnitCheckers.push_back(checkfn);
746
29
}
747
748
//===----------------------------------------------------------------------===//
749
// Implementation details.
750
//===----------------------------------------------------------------------===//
751
752
const CheckerManager::CachedStmtCheckers &
753
833k
CheckerManager::getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit) {
754
833k
  assert(S);
755
833k
756
833k
  unsigned Key = (S->getStmtClass() << 1) | unsigned(isPreVisit);
757
833k
  CachedStmtCheckersMapTy::iterator CCI = CachedStmtCheckersMap.find(Key);
758
833k
  if (CCI != CachedStmtCheckersMap.end())
759
825k
    return CCI->second;
760
7.95k
761
7.95k
  // Find the checkers that should run for this Stmt and cache them.
762
7.95k
  CachedStmtCheckers &Checkers = CachedStmtCheckersMap[Key];
763
121k
  for (unsigned i = 0, e = StmtCheckers.size(); 
i != e121k
;
++i113k
) {
764
113k
    StmtCheckerInfo &Info = StmtCheckers[i];
765
113k
    if (
Info.IsPreVisit == isPreVisit && 113k
Info.IsForStmtFn(S)57.0k
)
766
4.54k
      Checkers.push_back(Info.CheckFn);
767
113k
  }
768
833k
  return Checkers;
769
833k
}
770
771
567
CheckerManager::~CheckerManager() {
772
8.58k
  for (unsigned i = 0, e = CheckerDtors.size(); 
i != e8.58k
;
++i8.02k
)
773
8.02k
    CheckerDtors[i]();
774
567
}