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 using namespace clang; 7 using namespace ento; 8 9 namespace { 10 class MainCallChecker : public Checker<check::PreStmt<CallExpr>> { 11 mutable std::unique_ptr<BugType> BT; 12 13 public: 14 void checkPreStmt(const CallExpr *CE, CheckerContext &C) const; 15 }; 16 } // end anonymous namespace 17 18 void 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! 47 extern "C" void clang_registerCheckers(CheckerRegistry ®istry) { 48 registry.addChecker<MainCallChecker>( 49 "example.MainCallChecker", "Disallows calls to functions called main", 50 ""); 51 } 52 53 extern "C" const char clang_analyzerAPIVersionString[] = 54 CLANG_ANALYZER_API_VERSION_STRING; 55