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