Search code examples
c++clangcompiler-warningsclang-static-analyzer

How do I register my Clang Static Analyzer checker


I am fully aware that this question has previous answers. However, those answers are old and don't reflect what is happening in the current code base.

I have followed the steps in this guide for developing the checker, registering it with the engine, and testing it.

After some work, I was able to compile the code but when running clang -cc1 -analyzer-checker-help my checker is not visible. I Have noticed that a lot of the checkers aren't visible.

Do I need to explicitly enable the checker on the command line? If not what have I missed?

When I run clang --analyze test.cpp of clang -cc1 -analyze test.cpp my checker does not raise a warning. But others do, even those "not visible" in the clang -cc1 -analyzer-checker-help command.

Please do not point me into the direction of 6 year old documentation that is outdated. I want to know how to get this done.

My code:

MainCallChecker.cpp

using namespace clang;
using namespace ento;
namespace {
class MainCallChecker : public Checker<check::PreCall> {
  mutable std::unique_ptr<BugType> BT;

public:
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
};
}

void MainCallChecker::checkPreCall(const CallEvent &Call,
                                   CheckerContext &C) const {

  if(const IdentifierInfo *II = Call.getCalleeIdentifier()) {

    if(II ->isStr("main")) {

      if(!BT) {
        BT.reset(new BugType(this, "Call to main", "Example checker"));
        ExplodedNode *N = C.generateErrorNode();
        auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getCheckerName(), N);
        C.emitReport(std::move(R));
      }

    }

  }

}

void ento::registerMainCallChecker(CheckerManager &mgr){
  mgr.registerChecker<MainCallChecker>();
}

Checkers.td

def MainCallChecker : Checker<"MainCall">,
  HelpText<"MyChecker">,
  Documentation<NotDocumented>;

CMakeLists.txt

add_clang_library(clangStaticAnalyzerCheckers
.
.
MainCallChecker.cpp
.
.
)

test.cpp

typedef int (*main_t)(int, char **);
int main(int argc, char** argv) {
        main_t foo = main;
        int exit_code = foo(argc, argv);
        return exit_code;
        
}

Solution

  • UPDATE: A Clang contributor provided me a helpful answer that fixed my problem. via the llvm discorse