1#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
2#include "clang/StaticAnalyzer/Core/Checker.h"
3#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
4#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
5
6// This simple plugin is used by clang/test/Analysis/checker-plugins.c
7// to test the use of a checker that is defined in a plugin.
8
9using namespace clang;
10using namespace ento;
11
12namespace {
13class MainCallChecker : public Checker<check::PreStmt<CallExpr>> {
14
15 const BugType BT{this, "call to main", "example analyzer plugin"};
16
17public:
18 void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
19};
20} // end anonymous namespace
21
22void MainCallChecker::checkPreStmt(const CallExpr *CE,
23 CheckerContext &C) const {
24 const Expr *Callee = CE->getCallee();
25 const FunctionDecl *FD = C.getSVal(S: Callee).getAsFunctionDecl();
26
27 if (!FD)
28 return;
29
30 // Get the name of the callee.
31 IdentifierInfo *II = FD->getIdentifier();
32 if (!II) // if no identifier, not a simple C function
33 return;
34
35 if (II->isStr(Str: "main")) {
36 ExplodedNode *N = C.generateErrorNode();
37 if (!N)
38 return;
39
40 auto report =
41 std::make_unique<PathSensitiveBugReport>(args: BT, args: BT.getDescription(), args&: N);
42 report->addRange(R: Callee->getSourceRange());
43 C.emitReport(R: std::move(report));
44 }
45}
46
47// Register plugin!
48extern "C" void clang_registerCheckers(CheckerRegistry &Registry) {
49 Registry.addChecker<MainCallChecker>(FullName: "example.MainCallChecker",
50 Desc: "Example Description");
51}
52
53extern "C" const char clang_analyzerAPIVersionString[] =
54 CLANG_ANALYZER_API_VERSION_STRING;
55