[cfe-dev] Handling static analyzer diagnostics

Stefan Schulze Frielinghaus via cfe-dev cfe-dev at lists.llvm.org
Wed Jan 6 03:03:39 PST 2021


Hi all,

I've been playing around with the Static Analyzer in an external code tree and
came up with a couple of tests based upon GoogleTest.  Inspired by the unit
tests found in the clang source tree I came up with a PathDiagnosticConsumer
attached at the end of this mail.

All that works.  However, running the test suite also results in printing the
warning to stderr which somehow clutters the output of a test suite run.  I'm
wondering whether it is possible to silence a warning which I handle via my
DiagConsumer explicitly whereas all other warnings are still printed to stderr?

Cheers,
Stefan



class DiagConsumer : public PathDiagnosticConsumer {
  llvm::raw_ostream &Output;
public:
  DiagConsumer(llvm::raw_ostream &Output) : Output(Output) {}
  void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
                            FilesMade *filesMade) override {
    for (const auto *PD : Diags)
      Output << PD->getCheckerName() << ":" << PD->getShortDescription() << '\n';
  }
  StringRef getName() const override { return "Test"; }
};

class TestAction : public AnalysisAction {
  llvm::raw_ostream &DiagsOutput;
public:
  TestAction(llvm::raw_ostream &DiagsOutput) : DiagsOutput(DiagsOutput) {}
protected:
  std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &CI,
                                                        clang::StringRef InFile) override {
    std::unique_ptr<AnalysisASTConsumer> AnalysisConsumer = CreateAnalysisConsumer(CI);
    auto analyzerOpts = CI.getAnalyzerOpts();
    analyzerOpts->CheckersAndPackages = {{"foobar", true}};
    AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
      Registry.addChecker<Foobar>("foobar", "", "");
    });
    AnalysisConsumer->AddDiagnosticConsumer(new DiagConsumer(DiagsOutput));
    return std::move(AnalysisConsumer);
  }
};

TEST(X, Y) {
  std::string Diags;
  llvm::raw_string_ostream OS(Diags);
  auto Code = /* ... */
  EXPECT_TRUE(tooling::runToolOnCode(std::make_unique<TestAction>(OS), Code, "FileName.c"));
  EXPECT_EQ(Diags, "foobar:baz\n");
}


More information about the cfe-dev mailing list