xref: /llvm-project/clang/lib/Analysis/plugins/SampleAnalyzer/MainCallChecker.cpp (revision 72649423c043341c770516cd73aecde281730260)
1ccbda6b0SDon Hinton #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
2ccbda6b0SDon Hinton #include "clang/StaticAnalyzer/Core/Checker.h"
3ccbda6b0SDon Hinton #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
4ccbda6b0SDon Hinton #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
5ccbda6b0SDon Hinton 
6ccbda6b0SDon Hinton using namespace clang;
7ccbda6b0SDon Hinton using namespace ento;
8ccbda6b0SDon Hinton 
9ccbda6b0SDon Hinton namespace {
10ccbda6b0SDon Hinton class MainCallChecker : public Checker<check::PreStmt<CallExpr>> {
11ccbda6b0SDon Hinton   mutable std::unique_ptr<BugType> BT;
12ccbda6b0SDon Hinton 
13ccbda6b0SDon Hinton public:
14ccbda6b0SDon Hinton   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
15ccbda6b0SDon Hinton };
16ccbda6b0SDon Hinton } // end anonymous namespace
17ccbda6b0SDon Hinton 
checkPreStmt(const CallExpr * CE,CheckerContext & C) const18ccbda6b0SDon Hinton void MainCallChecker::checkPreStmt(const CallExpr *CE,
19ccbda6b0SDon Hinton                                    CheckerContext &C) const {
20ccbda6b0SDon Hinton   const Expr *Callee = CE->getCallee();
21ccbda6b0SDon Hinton   const FunctionDecl *FD = C.getSVal(Callee).getAsFunctionDecl();
22ccbda6b0SDon Hinton 
23ccbda6b0SDon Hinton   if (!FD)
24ccbda6b0SDon Hinton     return;
25ccbda6b0SDon Hinton 
26ccbda6b0SDon Hinton   // Get the name of the callee.
27ccbda6b0SDon Hinton   IdentifierInfo *II = FD->getIdentifier();
28ccbda6b0SDon Hinton   if (!II) // if no identifier, not a simple C function
29ccbda6b0SDon Hinton     return;
30ccbda6b0SDon Hinton 
31ccbda6b0SDon Hinton   if (II->isStr("main")) {
32ccbda6b0SDon Hinton     ExplodedNode *N = C.generateErrorNode();
33ccbda6b0SDon Hinton     if (!N)
34ccbda6b0SDon Hinton       return;
35ccbda6b0SDon Hinton 
36ccbda6b0SDon Hinton     if (!BT)
37ccbda6b0SDon Hinton       BT.reset(new BugType(this, "call to main", "example analyzer plugin"));
38ccbda6b0SDon Hinton 
392f169e7cSArtem Dergachev     auto report =
40*72649423SKristof Umann         std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
41ccbda6b0SDon Hinton     report->addRange(Callee->getSourceRange());
42ccbda6b0SDon Hinton     C.emitReport(std::move(report));
43ccbda6b0SDon Hinton   }
44ccbda6b0SDon Hinton }
45ccbda6b0SDon Hinton 
46ccbda6b0SDon Hinton // Register plugin!
clang_registerCheckers(CheckerRegistry & registry)47ccbda6b0SDon Hinton extern "C" void clang_registerCheckers(CheckerRegistry &registry) {
48ccbda6b0SDon Hinton   registry.addChecker<MainCallChecker>(
49ccbda6b0SDon Hinton       "example.MainCallChecker", "Disallows calls to functions called main",
50ccbda6b0SDon Hinton       "");
51ccbda6b0SDon Hinton }
52ccbda6b0SDon Hinton 
53ccbda6b0SDon Hinton extern "C" const char clang_analyzerAPIVersionString[] =
54ccbda6b0SDon Hinton     CLANG_ANALYZER_API_VERSION_STRING;
55