Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
Line
Count
Source (jump to first uncovered line)
1
//==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file defines checkers that display debugging information.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
14
#include "clang/Analysis/Analyses/Dominators.h"
15
#include "clang/Analysis/Analyses/LiveVariables.h"
16
#include "clang/Analysis/CallGraph.h"
17
#include "clang/StaticAnalyzer/Core/Checker.h"
18
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
19
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
20
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
21
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
22
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
23
#include "llvm/Support/Process.h"
24
25
using namespace clang;
26
using namespace ento;
27
28
//===----------------------------------------------------------------------===//
29
// DominatorsTreeDumper
30
//===----------------------------------------------------------------------===//
31
32
namespace {
33
class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
34
public:
35
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
36
7
                        BugReporter &BR) const {
37
7
    if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
38
7
      CFGDomTree Dom;
39
7
      Dom.buildDominatorTree(AC->getCFG());
40
7
      Dom.dump();
41
7
    }
42
7
  }
43
};
44
}
45
46
2
void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
47
2
  mgr.registerChecker<DominatorsTreeDumper>();
48
2
}
49
50
2
bool ento::shouldRegisterDominatorsTreeDumper(const LangOptions &LO) {
51
2
  return true;
52
2
}
53
54
//===----------------------------------------------------------------------===//
55
// PostDominatorsTreeDumper
56
//===----------------------------------------------------------------------===//
57
58
namespace {
59
class PostDominatorsTreeDumper : public Checker<check::ASTCodeBody> {
60
public:
61
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
62
7
                        BugReporter &BR) const {
63
7
    if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
64
7
      CFGPostDomTree Dom;
65
7
      Dom.buildDominatorTree(AC->getCFG());
66
7
      Dom.dump();
67
7
    }
68
7
  }
69
};
70
}
71
72
2
void ento::registerPostDominatorsTreeDumper(CheckerManager &mgr) {
73
2
  mgr.registerChecker<PostDominatorsTreeDumper>();
74
2
}
75
76
2
bool ento::shouldRegisterPostDominatorsTreeDumper(const LangOptions &LO) {
77
2
  return true;
78
2
}
79
80
//===----------------------------------------------------------------------===//
81
// ControlDependencyTreeDumper
82
//===----------------------------------------------------------------------===//
83
84
namespace {
85
class ControlDependencyTreeDumper : public Checker<check::ASTCodeBody> {
86
public:
87
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
88
7
                        BugReporter &BR) const {
89
7
    if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
90
7
      ControlDependencyCalculator Dom(AC->getCFG());
91
7
      Dom.dump();
92
7
    }
93
7
  }
94
};
95
}
96
97
2
void ento::registerControlDependencyTreeDumper(CheckerManager &mgr) {
98
2
  mgr.registerChecker<ControlDependencyTreeDumper>();
99
2
}
100
101
2
bool ento::shouldRegisterControlDependencyTreeDumper(const LangOptions &LO) {
102
2
  return true;
103
2
}
104
105
//===----------------------------------------------------------------------===//
106
// LiveVariablesDumper
107
//===----------------------------------------------------------------------===//
108
109
namespace {
110
class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
111
public:
112
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
113
0
                        BugReporter &BR) const {
114
0
    if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
115
0
      L->dumpBlockLiveness(mgr.getSourceManager());
116
0
    }
117
0
  }
118
};
119
}
120
121
0
void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
122
0
  mgr.registerChecker<LiveVariablesDumper>();
123
0
}
124
125
0
bool ento::shouldRegisterLiveVariablesDumper(const LangOptions &LO) {
126
0
  return true;
127
0
}
128
129
//===----------------------------------------------------------------------===//
130
// LiveStatementsDumper
131
//===----------------------------------------------------------------------===//
132
133
namespace {
134
class LiveStatementsDumper : public Checker<check::ASTCodeBody> {
135
public:
136
  void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr,
137
5
                        BugReporter &BR) const {
138
5
    if (LiveVariables *L = Mgr.getAnalysis<RelaxedLiveVariables>(D))
139
5
      L->dumpStmtLiveness(Mgr.getSourceManager());
140
5
  }
141
};
142
}
143
144
1
void ento::registerLiveStatementsDumper(CheckerManager &mgr) {
145
1
  mgr.registerChecker<LiveStatementsDumper>();
146
1
}
147
148
1
bool ento::shouldRegisterLiveStatementsDumper(const LangOptions &LO) {
149
1
  return true;
150
1
}
151
152
//===----------------------------------------------------------------------===//
153
// CFGViewer
154
//===----------------------------------------------------------------------===//
155
156
namespace {
157
class CFGViewer : public Checker<check::ASTCodeBody> {
158
public:
159
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
160
0
                        BugReporter &BR) const {
161
0
    if (CFG *cfg = mgr.getCFG(D)) {
162
0
      cfg->viewCFG(mgr.getLangOpts());
163
0
    }
164
0
  }
165
};
166
}
167
168
0
void ento::registerCFGViewer(CheckerManager &mgr) {
169
0
  mgr.registerChecker<CFGViewer>();
170
0
}
171
172
0
bool ento::shouldRegisterCFGViewer(const LangOptions &LO) {
173
0
  return true;
174
0
}
175
176
//===----------------------------------------------------------------------===//
177
// CFGDumper
178
//===----------------------------------------------------------------------===//
179
180
namespace {
181
class CFGDumper : public Checker<check::ASTCodeBody> {
182
public:
183
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
184
670
                        BugReporter &BR) const {
185
670
    PrintingPolicy Policy(mgr.getLangOpts());
186
670
    Policy.TerseOutput = true;
187
670
    Policy.PolishForDeclaration = true;
188
670
    D->print(llvm::errs(), Policy);
189
670
190
670
    if (CFG *cfg = mgr.getCFG(D)) {
191
670
      cfg->dump(mgr.getLangOpts(),
192
670
                llvm::sys::Process::StandardErrHasColors());
193
670
    }
194
670
  }
195
};
196
}
197
198
33
void ento::registerCFGDumper(CheckerManager &mgr) {
199
33
  mgr.registerChecker<CFGDumper>();
200
33
}
201
202
33
bool ento::shouldRegisterCFGDumper(const LangOptions &LO) {
203
33
  return true;
204
33
}
205
206
//===----------------------------------------------------------------------===//
207
// CallGraphViewer
208
//===----------------------------------------------------------------------===//
209
210
namespace {
211
class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
212
public:
213
  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
214
0
                    BugReporter &BR) const {
215
0
    CallGraph CG;
216
0
    CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
217
0
    CG.viewGraph();
218
0
  }
219
};
220
}
221
222
0
void ento::registerCallGraphViewer(CheckerManager &mgr) {
223
0
  mgr.registerChecker<CallGraphViewer>();
224
0
}
225
226
0
bool ento::shouldRegisterCallGraphViewer(const LangOptions &LO) {
227
0
  return true;
228
0
}
229
230
//===----------------------------------------------------------------------===//
231
// CallGraphDumper
232
//===----------------------------------------------------------------------===//
233
234
namespace {
235
class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
236
public:
237
  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
238
1
                    BugReporter &BR) const {
239
1
    CallGraph CG;
240
1
    CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
241
1
    CG.dump();
242
1
  }
243
};
244
}
245
246
1
void ento::registerCallGraphDumper(CheckerManager &mgr) {
247
1
  mgr.registerChecker<CallGraphDumper>();
248
1
}
249
250
1
bool ento::shouldRegisterCallGraphDumper(const LangOptions &LO) {
251
1
  return true;
252
1
}
253
254
//===----------------------------------------------------------------------===//
255
// ConfigDumper
256
//===----------------------------------------------------------------------===//
257
258
namespace {
259
class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
260
  typedef AnalyzerOptions::ConfigTable Table;
261
262
  static int compareEntry(const Table::MapEntryTy *const *LHS,
263
3.25k
                          const Table::MapEntryTy *const *RHS) {
264
3.25k
    return (*LHS)->getKey().compare((*RHS)->getKey());
265
3.25k
  }
266
267
public:
268
  void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
269
                                 AnalysisManager& mgr,
270
6
                                 BugReporter &BR) const {
271
6
    const Table &Config = mgr.options.Config;
272
6
273
6
    SmallVector<const Table::MapEntryTy *, 32> Keys;
274
537
    for (Table::const_iterator I = Config.begin(), E = Config.end(); I != E;
275
531
         ++I)
276
531
      Keys.push_back(&*I);
277
6
    llvm::array_pod_sort(Keys.begin(), Keys.end(), compareEntry);
278
6
279
6
    llvm::errs() << "[config]\n";
280
537
    for (unsigned I = 0, E = Keys.size(); I != E; 
++I531
)
281
531
      llvm::errs() << Keys[I]->getKey() << " = "
282
531
                   << (Keys[I]->second.empty() ? 
"\"\""12
:
Keys[I]->second519
)
283
531
                   << '\n';
284
6
285
6
    llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
286
6
  }
287
};
288
}
289
290
6
void ento::registerConfigDumper(CheckerManager &mgr) {
291
6
  mgr.registerChecker<ConfigDumper>();
292
6
}
293
294
6
bool ento::shouldRegisterConfigDumper(const LangOptions &LO) {
295
6
  return true;
296
6
}
297
298
//===----------------------------------------------------------------------===//
299
// ExplodedGraph Viewer
300
//===----------------------------------------------------------------------===//
301
302
namespace {
303
class ExplodedGraphViewer : public Checker< check::EndAnalysis > {
304
public:
305
0
  ExplodedGraphViewer() {}
306
0
  void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const {
307
0
    Eng.ViewGraph(0);
308
0
  }
309
};
310
311
}
312
313
0
void ento::registerExplodedGraphViewer(CheckerManager &mgr) {
314
0
  mgr.registerChecker<ExplodedGraphViewer>();
315
0
}
316
317
0
bool ento::shouldRegisterExplodedGraphViewer(const LangOptions &LO) {
318
0
  return true;
319
0
}
320
321
//===----------------------------------------------------------------------===//
322
// Emits a report for every Stmt that the analyzer visits.
323
//===----------------------------------------------------------------------===//
324
325
namespace {
326
327
class ReportStmts : public Checker<check::PreStmt<Stmt>> {
328
  BuiltinBug BT_stmtLoc{this, "Statement"};
329
330
public:
331
6
  void checkPreStmt(const Stmt *S, CheckerContext &C) const {
332
6
    ExplodedNode *Node = C.generateNonFatalErrorNode();
333
6
    if (!Node)
334
0
      return;
335
6
336
6
    auto Report = llvm::make_unique<BugReport>(BT_stmtLoc, "Statement", Node);
337
6
338
6
    C.emitReport(std::move(Report));
339
6
  }
340
};
341
342
} // end of anonymous namespace
343
344
1
void ento::registerReportStmts(CheckerManager &mgr) {
345
1
  mgr.registerChecker<ReportStmts>();
346
1
}
347
348
1
bool ento::shouldRegisterReportStmts(const LangOptions &LO) {
349
1
  return true;
350
1
}