MainCallChecker.cpp 1.6 KB

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