Clang Project

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