157d736fdSArgyrios Kyrtzidis //==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==//
257d736fdSArgyrios Kyrtzidis //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
657d736fdSArgyrios Kyrtzidis //
757d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
857d736fdSArgyrios Kyrtzidis //
973b75e01SJordan Rose // This file defines checkers that display debugging information.
1057d736fdSArgyrios Kyrtzidis //
1157d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
1257d736fdSArgyrios Kyrtzidis
1376a21502SKristof Umann #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
143a02247dSChandler Carruth #include "clang/Analysis/Analyses/Dominators.h"
153a02247dSChandler Carruth #include "clang/Analysis/Analyses/LiveVariables.h"
163a02247dSChandler Carruth #include "clang/Analysis/CallGraph.h"
176a5674ffSArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/Checker.h"
18efec1630SGabor Horvath #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
1957d736fdSArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
20efec1630SGabor Horvath #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
217925e3dbSAnna Zaks #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
227925e3dbSAnna Zaks #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
2372be32afSTed Kremenek #include "llvm/Support/Process.h"
2457d736fdSArgyrios Kyrtzidis
2557d736fdSArgyrios Kyrtzidis using namespace clang;
2657d736fdSArgyrios Kyrtzidis using namespace ento;
2757d736fdSArgyrios Kyrtzidis
2857d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
290062e749STed Kremenek // DominatorsTreeDumper
300062e749STed Kremenek //===----------------------------------------------------------------------===//
310062e749STed Kremenek
320062e749STed Kremenek namespace {
330062e749STed Kremenek class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
340062e749STed Kremenek public:
checkASTCodeBody(const Decl * D,AnalysisManager & mgr,BugReporter & BR) const350062e749STed Kremenek void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
360062e749STed Kremenek BugReporter &BR) const {
370062e749STed Kremenek if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
385e17ee1eSKristof Umann CFGDomTree Dom;
395e17ee1eSKristof Umann Dom.buildDominatorTree(AC->getCFG());
405e17ee1eSKristof Umann Dom.dump();
410062e749STed Kremenek }
420062e749STed Kremenek }
430062e749STed Kremenek };
44ab9db510SAlexander Kornienko }
450062e749STed Kremenek
registerDominatorsTreeDumper(CheckerManager & mgr)460062e749STed Kremenek void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
470062e749STed Kremenek mgr.registerChecker<DominatorsTreeDumper>();
480062e749STed Kremenek }
490062e749STed Kremenek
shouldRegisterDominatorsTreeDumper(const CheckerManager & mgr)50bda3dd0dSKirstóf Umann bool ento::shouldRegisterDominatorsTreeDumper(const CheckerManager &mgr) {
51058a7a45SKristof Umann return true;
52058a7a45SKristof Umann }
53058a7a45SKristof Umann
540062e749STed Kremenek //===----------------------------------------------------------------------===//
5571a9dc39SKristof Umann // PostDominatorsTreeDumper
5671a9dc39SKristof Umann //===----------------------------------------------------------------------===//
5771a9dc39SKristof Umann
5871a9dc39SKristof Umann namespace {
5971a9dc39SKristof Umann class PostDominatorsTreeDumper : public Checker<check::ASTCodeBody> {
6071a9dc39SKristof Umann public:
checkASTCodeBody(const Decl * D,AnalysisManager & mgr,BugReporter & BR) const6171a9dc39SKristof Umann void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
6271a9dc39SKristof Umann BugReporter &BR) const {
6371a9dc39SKristof Umann if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
645e17ee1eSKristof Umann CFGPostDomTree Dom;
655e17ee1eSKristof Umann Dom.buildDominatorTree(AC->getCFG());
665e17ee1eSKristof Umann Dom.dump();
6771a9dc39SKristof Umann }
6871a9dc39SKristof Umann }
6971a9dc39SKristof Umann };
7071a9dc39SKristof Umann }
7171a9dc39SKristof Umann
registerPostDominatorsTreeDumper(CheckerManager & mgr)7271a9dc39SKristof Umann void ento::registerPostDominatorsTreeDumper(CheckerManager &mgr) {
7371a9dc39SKristof Umann mgr.registerChecker<PostDominatorsTreeDumper>();
7471a9dc39SKristof Umann }
7571a9dc39SKristof Umann
shouldRegisterPostDominatorsTreeDumper(const CheckerManager & mgr)76bda3dd0dSKirstóf Umann bool ento::shouldRegisterPostDominatorsTreeDumper(const CheckerManager &mgr) {
7771a9dc39SKristof Umann return true;
7871a9dc39SKristof Umann }
7971a9dc39SKristof Umann
8071a9dc39SKristof Umann //===----------------------------------------------------------------------===//
815e17ee1eSKristof Umann // ControlDependencyTreeDumper
825e17ee1eSKristof Umann //===----------------------------------------------------------------------===//
835e17ee1eSKristof Umann
845e17ee1eSKristof Umann namespace {
855e17ee1eSKristof Umann class ControlDependencyTreeDumper : public Checker<check::ASTCodeBody> {
865e17ee1eSKristof Umann public:
checkASTCodeBody(const Decl * D,AnalysisManager & mgr,BugReporter & BR) const875e17ee1eSKristof Umann void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
885e17ee1eSKristof Umann BugReporter &BR) const {
895e17ee1eSKristof Umann if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
905e17ee1eSKristof Umann ControlDependencyCalculator Dom(AC->getCFG());
915e17ee1eSKristof Umann Dom.dump();
925e17ee1eSKristof Umann }
935e17ee1eSKristof Umann }
945e17ee1eSKristof Umann };
955e17ee1eSKristof Umann }
965e17ee1eSKristof Umann
registerControlDependencyTreeDumper(CheckerManager & mgr)975e17ee1eSKristof Umann void ento::registerControlDependencyTreeDumper(CheckerManager &mgr) {
985e17ee1eSKristof Umann mgr.registerChecker<ControlDependencyTreeDumper>();
995e17ee1eSKristof Umann }
1005e17ee1eSKristof Umann
shouldRegisterControlDependencyTreeDumper(const CheckerManager & mgr)101bda3dd0dSKirstóf Umann bool ento::shouldRegisterControlDependencyTreeDumper(const CheckerManager &mgr) {
1025e17ee1eSKristof Umann return true;
1035e17ee1eSKristof Umann }
1045e17ee1eSKristof Umann
1055e17ee1eSKristof Umann //===----------------------------------------------------------------------===//
10657d736fdSArgyrios Kyrtzidis // LiveVariablesDumper
10757d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
10857d736fdSArgyrios Kyrtzidis
10957d736fdSArgyrios Kyrtzidis namespace {
1106a5674ffSArgyrios Kyrtzidis class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
11157d736fdSArgyrios Kyrtzidis public:
checkASTCodeBody(const Decl * D,AnalysisManager & mgr,BugReporter & BR) const11257d736fdSArgyrios Kyrtzidis void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
11357d736fdSArgyrios Kyrtzidis BugReporter &BR) const {
114dccc2b22STed Kremenek if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
11557d736fdSArgyrios Kyrtzidis L->dumpBlockLiveness(mgr.getSourceManager());
11657d736fdSArgyrios Kyrtzidis }
11757d736fdSArgyrios Kyrtzidis }
11857d736fdSArgyrios Kyrtzidis };
119ab9db510SAlexander Kornienko }
12057d736fdSArgyrios Kyrtzidis
registerLiveVariablesDumper(CheckerManager & mgr)12157d736fdSArgyrios Kyrtzidis void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
12257d736fdSArgyrios Kyrtzidis mgr.registerChecker<LiveVariablesDumper>();
12357d736fdSArgyrios Kyrtzidis }
12457d736fdSArgyrios Kyrtzidis
shouldRegisterLiveVariablesDumper(const CheckerManager & mgr)125bda3dd0dSKirstóf Umann bool ento::shouldRegisterLiveVariablesDumper(const CheckerManager &mgr) {
126058a7a45SKristof Umann return true;
127058a7a45SKristof Umann }
128058a7a45SKristof Umann
12957d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
130dda42164SArtem Dergachev // LiveStatementsDumper
131dda42164SArtem Dergachev //===----------------------------------------------------------------------===//
132dda42164SArtem Dergachev
133dda42164SArtem Dergachev namespace {
134dd1d5488SKristóf Umann class LiveExpressionsDumper : public Checker<check::ASTCodeBody> {
135dda42164SArtem Dergachev public:
checkASTCodeBody(const Decl * D,AnalysisManager & Mgr,BugReporter & BR) const136dda42164SArtem Dergachev void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr,
137dda42164SArtem Dergachev BugReporter &BR) const {
138dda42164SArtem Dergachev if (LiveVariables *L = Mgr.getAnalysis<RelaxedLiveVariables>(D))
139dd1d5488SKristóf Umann L->dumpExprLiveness(Mgr.getSourceManager());
140dda42164SArtem Dergachev }
141dda42164SArtem Dergachev };
142dda42164SArtem Dergachev }
143dda42164SArtem Dergachev
registerLiveExpressionsDumper(CheckerManager & mgr)144dd1d5488SKristóf Umann void ento::registerLiveExpressionsDumper(CheckerManager &mgr) {
145dd1d5488SKristóf Umann mgr.registerChecker<LiveExpressionsDumper>();
146dda42164SArtem Dergachev }
147dda42164SArtem Dergachev
shouldRegisterLiveExpressionsDumper(const CheckerManager & mgr)148dd1d5488SKristóf Umann bool ento::shouldRegisterLiveExpressionsDumper(const CheckerManager &mgr) {
149058a7a45SKristof Umann return true;
150058a7a45SKristof Umann }
151058a7a45SKristof Umann
152dda42164SArtem Dergachev //===----------------------------------------------------------------------===//
15357d736fdSArgyrios Kyrtzidis // CFGViewer
15457d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
15557d736fdSArgyrios Kyrtzidis
15657d736fdSArgyrios Kyrtzidis namespace {
1576a5674ffSArgyrios Kyrtzidis class CFGViewer : public Checker<check::ASTCodeBody> {
15857d736fdSArgyrios Kyrtzidis public:
checkASTCodeBody(const Decl * D,AnalysisManager & mgr,BugReporter & BR) const15957d736fdSArgyrios Kyrtzidis void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
16057d736fdSArgyrios Kyrtzidis BugReporter &BR) const {
16157d736fdSArgyrios Kyrtzidis if (CFG *cfg = mgr.getCFG(D)) {
162bbafb8a7SDavid Blaikie cfg->viewCFG(mgr.getLangOpts());
16357d736fdSArgyrios Kyrtzidis }
16457d736fdSArgyrios Kyrtzidis }
16557d736fdSArgyrios Kyrtzidis };
166ab9db510SAlexander Kornienko }
16757d736fdSArgyrios Kyrtzidis
registerCFGViewer(CheckerManager & mgr)16857d736fdSArgyrios Kyrtzidis void ento::registerCFGViewer(CheckerManager &mgr) {
16957d736fdSArgyrios Kyrtzidis mgr.registerChecker<CFGViewer>();
17057d736fdSArgyrios Kyrtzidis }
17157d736fdSArgyrios Kyrtzidis
shouldRegisterCFGViewer(const CheckerManager & mgr)172bda3dd0dSKirstóf Umann bool ento::shouldRegisterCFGViewer(const CheckerManager &mgr) {
173058a7a45SKristof Umann return true;
174058a7a45SKristof Umann }
175058a7a45SKristof Umann
17657d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
17757d736fdSArgyrios Kyrtzidis // CFGDumper
17857d736fdSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
17957d736fdSArgyrios Kyrtzidis
18057d736fdSArgyrios Kyrtzidis namespace {
1816a5674ffSArgyrios Kyrtzidis class CFGDumper : public Checker<check::ASTCodeBody> {
18257d736fdSArgyrios Kyrtzidis public:
checkASTCodeBody(const Decl * D,AnalysisManager & mgr,BugReporter & BR) const18357d736fdSArgyrios Kyrtzidis void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
18457d736fdSArgyrios Kyrtzidis BugReporter &BR) const {
185e02e96a6SJordan Rose PrintingPolicy Policy(mgr.getLangOpts());
186e02e96a6SJordan Rose Policy.TerseOutput = true;
187e02e96a6SJordan Rose Policy.PolishForDeclaration = true;
188e02e96a6SJordan Rose D->print(llvm::errs(), Policy);
189e02e96a6SJordan Rose
19057d736fdSArgyrios Kyrtzidis if (CFG *cfg = mgr.getCFG(D)) {
191bbafb8a7SDavid Blaikie cfg->dump(mgr.getLangOpts(),
19272be32afSTed Kremenek llvm::sys::Process::StandardErrHasColors());
19357d736fdSArgyrios Kyrtzidis }
19457d736fdSArgyrios Kyrtzidis }
19557d736fdSArgyrios Kyrtzidis };
196ab9db510SAlexander Kornienko }
19757d736fdSArgyrios Kyrtzidis
registerCFGDumper(CheckerManager & mgr)19857d736fdSArgyrios Kyrtzidis void ento::registerCFGDumper(CheckerManager &mgr) {
19957d736fdSArgyrios Kyrtzidis mgr.registerChecker<CFGDumper>();
20057d736fdSArgyrios Kyrtzidis }
201c000e7edSAnna Zaks
shouldRegisterCFGDumper(const CheckerManager & mgr)202bda3dd0dSKirstóf Umann bool ento::shouldRegisterCFGDumper(const CheckerManager &mgr) {
203058a7a45SKristof Umann return true;
204058a7a45SKristof Umann }
205058a7a45SKristof Umann
206c000e7edSAnna Zaks //===----------------------------------------------------------------------===//
207c000e7edSAnna Zaks // CallGraphViewer
208c000e7edSAnna Zaks //===----------------------------------------------------------------------===//
209c000e7edSAnna Zaks
210c000e7edSAnna Zaks namespace {
211c000e7edSAnna Zaks class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
212c000e7edSAnna Zaks public:
checkASTDecl(const TranslationUnitDecl * TU,AnalysisManager & mgr,BugReporter & BR) const213c000e7edSAnna Zaks void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
214c000e7edSAnna Zaks BugReporter &BR) const {
215c000e7edSAnna Zaks CallGraph CG;
216c000e7edSAnna Zaks CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
217c000e7edSAnna Zaks CG.viewGraph();
218c000e7edSAnna Zaks }
219c000e7edSAnna Zaks };
220ab9db510SAlexander Kornienko }
221c000e7edSAnna Zaks
registerCallGraphViewer(CheckerManager & mgr)222c000e7edSAnna Zaks void ento::registerCallGraphViewer(CheckerManager &mgr) {
223c000e7edSAnna Zaks mgr.registerChecker<CallGraphViewer>();
224c000e7edSAnna Zaks }
225c000e7edSAnna Zaks
shouldRegisterCallGraphViewer(const CheckerManager & mgr)226bda3dd0dSKirstóf Umann bool ento::shouldRegisterCallGraphViewer(const CheckerManager &mgr) {
227058a7a45SKristof Umann return true;
228058a7a45SKristof Umann }
229058a7a45SKristof Umann
230c000e7edSAnna Zaks //===----------------------------------------------------------------------===//
231c000e7edSAnna Zaks // CallGraphDumper
232c000e7edSAnna Zaks //===----------------------------------------------------------------------===//
233c000e7edSAnna Zaks
234c000e7edSAnna Zaks namespace {
235c000e7edSAnna Zaks class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
236c000e7edSAnna Zaks public:
checkASTDecl(const TranslationUnitDecl * TU,AnalysisManager & mgr,BugReporter & BR) const237c000e7edSAnna Zaks void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
238c000e7edSAnna Zaks BugReporter &BR) const {
239c000e7edSAnna Zaks CallGraph CG;
240c000e7edSAnna Zaks CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
241c000e7edSAnna Zaks CG.dump();
242c000e7edSAnna Zaks }
243c000e7edSAnna Zaks };
244ab9db510SAlexander Kornienko }
245c000e7edSAnna Zaks
registerCallGraphDumper(CheckerManager & mgr)246c000e7edSAnna Zaks void ento::registerCallGraphDumper(CheckerManager &mgr) {
247c000e7edSAnna Zaks mgr.registerChecker<CallGraphDumper>();
248c000e7edSAnna Zaks }
24986917fdbSTed Kremenek
shouldRegisterCallGraphDumper(const CheckerManager & mgr)250bda3dd0dSKirstóf Umann bool ento::shouldRegisterCallGraphDumper(const CheckerManager &mgr) {
251058a7a45SKristof Umann return true;
252058a7a45SKristof Umann }
25386917fdbSTed Kremenek
25486917fdbSTed Kremenek //===----------------------------------------------------------------------===//
25586917fdbSTed Kremenek // ConfigDumper
25686917fdbSTed Kremenek //===----------------------------------------------------------------------===//
25786917fdbSTed Kremenek
25886917fdbSTed Kremenek namespace {
25986917fdbSTed Kremenek class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
260a92b80f8SBenjamin Kramer typedef AnalyzerOptions::ConfigTable Table;
261a92b80f8SBenjamin Kramer
compareEntry(const Table::MapEntryTy * const * LHS,const Table::MapEntryTy * const * RHS)2624cadf292SBenjamin Kramer static int compareEntry(const Table::MapEntryTy *const *LHS,
2634cadf292SBenjamin Kramer const Table::MapEntryTy *const *RHS) {
2644cadf292SBenjamin Kramer return (*LHS)->getKey().compare((*RHS)->getKey());
2654cadf292SBenjamin Kramer }
2664cadf292SBenjamin Kramer
26786917fdbSTed Kremenek public:
checkEndOfTranslationUnit(const TranslationUnitDecl * TU,AnalysisManager & mgr,BugReporter & BR) const26886917fdbSTed Kremenek void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
26986917fdbSTed Kremenek AnalysisManager& mgr,
27086917fdbSTed Kremenek BugReporter &BR) const {
271a92b80f8SBenjamin Kramer const Table &Config = mgr.options.Config;
27286917fdbSTed Kremenek
273a92b80f8SBenjamin Kramer SmallVector<const Table::MapEntryTy *, 32> Keys;
274a92b80f8SBenjamin Kramer for (Table::const_iterator I = Config.begin(), E = Config.end(); I != E;
275a92b80f8SBenjamin Kramer ++I)
276a92b80f8SBenjamin Kramer Keys.push_back(&*I);
2774cadf292SBenjamin Kramer llvm::array_pod_sort(Keys.begin(), Keys.end(), compareEntry);
27886917fdbSTed Kremenek
27986917fdbSTed Kremenek llvm::errs() << "[config]\n";
280a92b80f8SBenjamin Kramer for (unsigned I = 0, E = Keys.size(); I != E; ++I)
281549f9cd4SKristof Umann llvm::errs() << Keys[I]->getKey() << " = "
282549f9cd4SKristof Umann << (Keys[I]->second.empty() ? "\"\"" : Keys[I]->second)
283549f9cd4SKristof Umann << '\n';
28486917fdbSTed Kremenek }
28586917fdbSTed Kremenek };
286ab9db510SAlexander Kornienko }
28786917fdbSTed Kremenek
registerConfigDumper(CheckerManager & mgr)28886917fdbSTed Kremenek void ento::registerConfigDumper(CheckerManager &mgr) {
28986917fdbSTed Kremenek mgr.registerChecker<ConfigDumper>();
29086917fdbSTed Kremenek }
2917925e3dbSAnna Zaks
shouldRegisterConfigDumper(const CheckerManager & mgr)292bda3dd0dSKirstóf Umann bool ento::shouldRegisterConfigDumper(const CheckerManager &mgr) {
293058a7a45SKristof Umann return true;
294058a7a45SKristof Umann }
295058a7a45SKristof Umann
2967925e3dbSAnna Zaks //===----------------------------------------------------------------------===//
2977925e3dbSAnna Zaks // ExplodedGraph Viewer
2987925e3dbSAnna Zaks //===----------------------------------------------------------------------===//
2997925e3dbSAnna Zaks
3007925e3dbSAnna Zaks namespace {
3017925e3dbSAnna Zaks class ExplodedGraphViewer : public Checker< check::EndAnalysis > {
3027925e3dbSAnna Zaks public:
ExplodedGraphViewer()3037925e3dbSAnna Zaks ExplodedGraphViewer() {}
checkEndAnalysis(ExplodedGraph & G,BugReporter & B,ExprEngine & Eng) const3047925e3dbSAnna Zaks void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const {
305*40446663SKazu Hirata Eng.ViewGraph(false);
3067925e3dbSAnna Zaks }
3077925e3dbSAnna Zaks };
3087925e3dbSAnna Zaks
3097925e3dbSAnna Zaks }
3107925e3dbSAnna Zaks
registerExplodedGraphViewer(CheckerManager & mgr)3117925e3dbSAnna Zaks void ento::registerExplodedGraphViewer(CheckerManager &mgr) {
3127925e3dbSAnna Zaks mgr.registerChecker<ExplodedGraphViewer>();
3137925e3dbSAnna Zaks }
314efec1630SGabor Horvath
shouldRegisterExplodedGraphViewer(const CheckerManager & mgr)315bda3dd0dSKirstóf Umann bool ento::shouldRegisterExplodedGraphViewer(const CheckerManager &mgr) {
316058a7a45SKristof Umann return true;
317058a7a45SKristof Umann }
3184962816eSKristof Umann
3194962816eSKristof Umann //===----------------------------------------------------------------------===//
3204962816eSKristof Umann // Emits a report for every Stmt that the analyzer visits.
3214962816eSKristof Umann //===----------------------------------------------------------------------===//
3224962816eSKristof Umann
3234962816eSKristof Umann namespace {
3244962816eSKristof Umann
3254962816eSKristof Umann class ReportStmts : public Checker<check::PreStmt<Stmt>> {
3264962816eSKristof Umann BuiltinBug BT_stmtLoc{this, "Statement"};
3274962816eSKristof Umann
3284962816eSKristof Umann public:
checkPreStmt(const Stmt * S,CheckerContext & C) const3294962816eSKristof Umann void checkPreStmt(const Stmt *S, CheckerContext &C) const {
3304962816eSKristof Umann ExplodedNode *Node = C.generateNonFatalErrorNode();
3314962816eSKristof Umann if (!Node)
3324962816eSKristof Umann return;
3334962816eSKristof Umann
3342f169e7cSArtem Dergachev auto Report =
3352f169e7cSArtem Dergachev std::make_unique<PathSensitiveBugReport>(BT_stmtLoc, "Statement", Node);
3364962816eSKristof Umann
3374962816eSKristof Umann C.emitReport(std::move(Report));
3384962816eSKristof Umann }
3394962816eSKristof Umann };
3404962816eSKristof Umann
3414962816eSKristof Umann } // end of anonymous namespace
3424962816eSKristof Umann
registerReportStmts(CheckerManager & mgr)3434962816eSKristof Umann void ento::registerReportStmts(CheckerManager &mgr) {
3444962816eSKristof Umann mgr.registerChecker<ReportStmts>();
3454962816eSKristof Umann }
3464962816eSKristof Umann
shouldRegisterReportStmts(const CheckerManager & mgr)347bda3dd0dSKirstóf Umann bool ento::shouldRegisterReportStmts(const CheckerManager &mgr) {
3484962816eSKristof Umann return true;
3494962816eSKristof Umann }
350