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