[clang] 58884eb - [analyzer][NFC] Refactor the checker registration unit test file

Kirstóf Umann via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 9 08:48:10 PDT 2020


Author: Kirstóf Umann
Date: 2020-03-09T16:38:30+01:00
New Revision: 58884eb6489880646896d72fcd723813f8a13299

URL: https://github.com/llvm/llvm-project/commit/58884eb6489880646896d72fcd723813f8a13299
DIFF: https://github.com/llvm/llvm-project/commit/58884eb6489880646896d72fcd723813f8a13299.diff

LOG: [analyzer][NFC] Refactor the checker registration unit test file

Nothing exciting to see here! The new interface allows for more fine tuning
(register but disable a checker, add custom checker registry functions, etc),
that was basically the point.

Differential Revision: https://reviews.llvm.org/D67335

Added: 
    clang/unittests/StaticAnalyzer/CheckerRegistration.h

Modified: 
    clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
    clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
index bc258160ada4..269c226f2e1d 100644
--- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
+++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
@@ -204,16 +204,14 @@ class CheckerRegistry {
 
   using PackageInfoList = llvm::SmallVector<PackageInfo, 0>;
 
-private:
-  template <typename T> static void initializeManager(CheckerManager &mgr) {
+  template <typename T> static void addToCheckerMgr(CheckerManager &mgr) {
     mgr.registerChecker<T>();
   }
 
-  template <typename T> static bool returnTrue(const LangOptions &LO) {
+  static bool returnTrue(const LangOptions &LO) {
     return true;
   }
 
-public:
   /// Adds a checker to the registry. Use this non-templated overload when your
   /// checker requires custom initialization.
   void addChecker(InitializationFunction Fn, ShouldRegisterFunction sfn,
@@ -227,9 +225,8 @@ class CheckerRegistry {
                   bool IsHidden = false) {
     // Avoid MSVC's Compiler Error C2276:
     // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
-    addChecker(&CheckerRegistry::initializeManager<T>,
-               &CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri,
-               IsHidden);
+    addChecker(&CheckerRegistry::addToCheckerMgr<T>,
+               &CheckerRegistry::returnTrue, FullName, Desc, DocsUri, IsHidden);
   }
 
   /// Makes the checker with the full name \p fullName depends on the checker

diff  --git a/clang/unittests/StaticAnalyzer/CheckerRegistration.h b/clang/unittests/StaticAnalyzer/CheckerRegistration.h
new file mode 100644
index 000000000000..0bbed9b7784f
--- /dev/null
+++ b/clang/unittests/StaticAnalyzer/CheckerRegistration.h
@@ -0,0 +1,81 @@
+//===- unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
+#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
+#include "clang/Tooling/Tooling.h"
+
+namespace clang {
+namespace ento {
+
+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"; }
+};
+
+using AddCheckerFn = void(AnalysisASTConsumer &AnalysisConsumer,
+                          AnalyzerOptions &AnOpts);
+
+template <AddCheckerFn Fn1, AddCheckerFn Fn2, AddCheckerFn... Fns>
+void addChecker(AnalysisASTConsumer &AnalysisConsumer,
+                AnalyzerOptions &AnOpts) {
+  Fn1(AnalysisConsumer, AnOpts);
+  addChecker<Fn2, Fns...>(AnalysisConsumer, AnOpts);
+}
+
+template <AddCheckerFn Fn1>
+void addChecker(AnalysisASTConsumer &AnalysisConsumer,
+                AnalyzerOptions &AnOpts) {
+  Fn1(AnalysisConsumer, AnOpts);
+}
+
+template <AddCheckerFn... Fns>
+class TestAction : public ASTFrontendAction {
+  llvm::raw_ostream &DiagsOutput;
+
+public:
+  TestAction(llvm::raw_ostream &DiagsOutput) : DiagsOutput(DiagsOutput) {}
+
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
+                                                 StringRef File) override {
+    std::unique_ptr<AnalysisASTConsumer> AnalysisConsumer =
+        CreateAnalysisConsumer(Compiler);
+    AnalysisConsumer->AddDiagnosticConsumer(new DiagConsumer(DiagsOutput));
+    addChecker<Fns...>(*AnalysisConsumer, *Compiler.getAnalyzerOpts());
+    return std::move(AnalysisConsumer);
+  }
+};
+
+template <AddCheckerFn... Fns>
+bool runCheckerOnCode(const std::string &Code, std::string &Diags) {
+  llvm::raw_string_ostream OS(Diags);
+  return tooling::runToolOnCode(std::make_unique<TestAction<Fns...>>(OS), Code);
+}
+
+template <AddCheckerFn... Fns>
+bool runCheckerOnCode(const std::string &Code) {
+  std::string Diags;
+  return runCheckerOnCode<Fns...>(Code, Diags);
+}
+
+} // namespace ento
+} // namespace clang

diff  --git a/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp b/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
index 4f504d2384cf..d0cf291eb2b8 100644
--- a/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
+++ b/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
@@ -6,11 +6,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "CheckerRegistration.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
 #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
 #include "clang/Tooling/Tooling.h"
@@ -20,53 +22,10 @@ namespace clang {
 namespace ento {
 namespace {
 
-template <typename CheckerT>
-class TestAction : public ASTFrontendAction {
-  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();
-    }
-
-    StringRef getName() const override { return "Test"; }
-  };
-
-  llvm::raw_ostream &DiagsOutput;
-
-public:
-  TestAction(llvm::raw_ostream &DiagsOutput) : DiagsOutput(DiagsOutput) {}
-
-  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
-                                                 StringRef File) override {
-    std::unique_ptr<AnalysisASTConsumer> AnalysisConsumer =
-        CreateAnalysisConsumer(Compiler);
-    AnalysisConsumer->AddDiagnosticConsumer(new DiagConsumer(DiagsOutput));
-    Compiler.getAnalyzerOpts()->CheckersAndPackages = {
-        {"custom.CustomChecker", true}};
-    AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
-      Registry.addChecker<CheckerT>("custom.CustomChecker", "Description", "");
-    });
-    return std::move(AnalysisConsumer);
-  }
-};
-
-template <typename CheckerT>
-bool runCheckerOnCode(const std::string &Code, std::string &Diags) {
-  llvm::raw_string_ostream OS(Diags);
-  return tooling::runToolOnCode(std::make_unique<TestAction<CheckerT>>(OS),
-                                Code);
-}
-template <typename CheckerT>
-bool runCheckerOnCode(const std::string &Code) {
-  std::string Diags;
-  return runCheckerOnCode<CheckerT>(Code, Diags);
-}
-
+//===----------------------------------------------------------------------===//
+// Just a minimal test for how checker registration works with statically
+// linked, non TableGen generated checkers.
+//===----------------------------------------------------------------------===//
 
 class CustomChecker : public Checker<check::ASTCodeBody> {
 public:
@@ -78,12 +37,25 @@ class CustomChecker : public Checker<check::ASTCodeBody> {
   }
 };
 
+void addCustomChecker(AnalysisASTConsumer &AnalysisConsumer,
+                      AnalyzerOptions &AnOpts) {
+  AnOpts.CheckersAndPackages = {{"custom.CustomChecker", true}};
+  AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
+    Registry.addChecker<CustomChecker>("custom.CustomChecker", "Description",
+                                       "");
+  });
+}
+
 TEST(RegisterCustomCheckers, RegisterChecker) {
   std::string Diags;
-  EXPECT_TRUE(runCheckerOnCode<CustomChecker>("void f() {;}", Diags));
-  EXPECT_EQ(Diags, "custom.CustomChecker:Custom diagnostic description");
+  EXPECT_TRUE(runCheckerOnCode<addCustomChecker>("void f() {;}", Diags));
+  EXPECT_EQ(Diags, "custom.CustomChecker:Custom diagnostic description\n");
 }
 
+//===----------------------------------------------------------------------===//
+// Pretty much the same.
+//===----------------------------------------------------------------------===//
+
 class LocIncDecChecker : public Checker<check::Location> {
 public:
   void checkLocation(SVal Loc, bool IsLoad, const Stmt *S,
@@ -95,11 +67,20 @@ class LocIncDecChecker : public Checker<check::Location> {
   }
 };
 
+void addLocIncDecChecker(AnalysisASTConsumer &AnalysisConsumer,
+                         AnalyzerOptions &AnOpts) {
+  AnOpts.CheckersAndPackages = {{"test.LocIncDecChecker", true}};
+  AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
+    Registry.addChecker<CustomChecker>("test.LocIncDecChecker", "Description",
+                                       "");
+  });
+}
+
 TEST(RegisterCustomCheckers, CheckLocationIncDec) {
   EXPECT_TRUE(
-      runCheckerOnCode<LocIncDecChecker>("void f() { int *p; (*p)++; }"));
+      runCheckerOnCode<addLocIncDecChecker>("void f() { int *p; (*p)++; }"));
 }
 
-}
-}
-}
+} // namespace
+} // namespace ento
+} // namespace clang


        


More information about the cfe-commits mailing list