[analyzer][NFC] Fix inconsistent references to checkers as "checks"
authorKristof Umann <kristof.umann@ericsson.com>
Thu, 12 Sep 2019 19:09:24 +0000 (19:09 +0000)
committerKristof Umann <kristof.umann@ericsson.com>
Thu, 12 Sep 2019 19:09:24 +0000 (19:09 +0000)
Traditionally, clang-tidy uses the term check, and the analyzer uses checker,
but in the very early years, this wasn't the case, and code originating from the
early 2010's still incorrectly refer to checkers as checks.

This patch attempts to hunt down most of these, aiming to refer to checkers as
checkers, but preserve references to callback functions (like checkPreCall) as
checks.

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

llvm-svn: 371760

32 files changed:
clang/include/clang/Analysis/PathDiagnostic.h
clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
clang/include/clang/StaticAnalyzer/Core/Checker.h
clang/include/clang/StaticAnalyzer/Core/CheckerManager.h
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
clang/lib/Analysis/PathDiagnostic.cpp
clang/lib/Analysis/plugins/SampleAnalyzer/MainCallChecker.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
clang/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp
clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
clang/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
clang/lib/StaticAnalyzer/Core/BugReporter.cpp
clang/lib/StaticAnalyzer/Core/Checker.cpp
clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp

index fdab18e..6730057 100644 (file)
@@ -725,7 +725,7 @@ using FilesToLineNumsMap = std::map<FileID, std::set<unsigned>>;
 ///  diagnostic.  It represents an ordered-collection of PathDiagnosticPieces,
 ///  each which represent the pieces of the path.
 class PathDiagnostic : public llvm::FoldingSetNode {
-  std::string CheckName;
+  std::string CheckerName;
   const Decl *DeclWithIssue;
   std::string BugType;
   std::string VerboseDesc;
@@ -749,7 +749,7 @@ class PathDiagnostic : public llvm::FoldingSetNode {
 
 public:
   PathDiagnostic() = delete;
-  PathDiagnostic(StringRef CheckName, const Decl *DeclWithIssue,
+  PathDiagnostic(StringRef CheckerName, const Decl *DeclWithIssue,
                  StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
                  StringRef category, PathDiagnosticLocation LocationToUnique,
                  const Decl *DeclToUnique,
@@ -798,7 +798,7 @@ public:
     return ShortDesc.empty() ? VerboseDesc : ShortDesc;
   }
 
-  StringRef getCheckName() const { return CheckName; }
+  StringRef getCheckerName() const { return CheckerName; }
   StringRef getBugType() const { return BugType; }
   StringRef getCategory() const { return Category; }
 
index 609932a..04d611a 100644 (file)
@@ -163,41 +163,15 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
 public:
   using ConfigTable = llvm::StringMap<std::string>;
 
+  /// Retrieves the list of checkers generated from Checkers.td. This doesn't
+  /// contain statically linked but non-generated checkers and plugin checkers!
   static std::vector<StringRef>
-  getRegisteredCheckers(bool IncludeExperimental = false) {
-    static const StringRef StaticAnalyzerChecks[] = {
-#define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) FULLNAME,
-#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
-#undef CHECKER
-#undef GET_CHECKERS
-    };
-    std::vector<StringRef> Checkers;
-    for (StringRef CheckerName : StaticAnalyzerChecks) {
-      if (!CheckerName.startswith("debug.") &&
-          (IncludeExperimental || !CheckerName.startswith("alpha.")))
-        Checkers.push_back(CheckerName);
-    }
-    return Checkers;
-  }
+  getRegisteredCheckers(bool IncludeExperimental = false);
 
+  /// Retrieves the list of packages generated from Checkers.td. This doesn't
+  /// contain statically linked but non-generated packages and plugin packages!
   static std::vector<StringRef>
-  getRegisteredPackages(bool IncludeExperimental = false) {
-    static const StringRef StaticAnalyzerPackages[] = {
-#define GET_PACKAGES
-#define PACKAGE(FULLNAME) FULLNAME,
-#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
-#undef PACKAGE
-#undef GET_PACKAGES
-    };
-    std::vector<StringRef> Packages;
-    for (StringRef PackageName : StaticAnalyzerPackages) {
-      if (PackageName != "debug" &&
-          (IncludeExperimental || PackageName != "alpha"))
-        Packages.push_back(PackageName);
-    }
-    return Packages;
-  }
+  getRegisteredPackages(bool IncludeExperimental = false);
 
   /// Convenience function for printing options or checkers and their
   /// description in a formatted manner. If \p MinLineWidth is set to 0, no line
@@ -247,12 +221,12 @@ public:
   /// The maximum number of times the analyzer visits a block.
   unsigned maxBlockVisitOnPath;
 
-  /// Disable all analyzer checks.
+  /// Disable all analyzer checkers.
   ///
-  /// This flag allows one to disable analyzer checks on the code processed by
+  /// This flag allows one to disable analyzer checkers on the code processed by
   /// the given analysis consumer. Note, the code will get parsed and the
   /// command-line options will get checked.
-  unsigned DisableAllChecks : 1;
+  unsigned DisableAllCheckers : 1;
 
   unsigned ShowCheckerHelp : 1;
   unsigned ShowCheckerHelpAlpha : 1;
@@ -327,7 +301,7 @@ public:
   }
 
   AnalyzerOptions()
-      : DisableAllChecks(false), ShowCheckerHelp(false),
+      : DisableAllCheckers(false), ShowCheckerHelp(false),
         ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
         ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false),
         ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
@@ -345,7 +319,7 @@ public:
   /// If an option value is not provided, returns the given \p DefaultVal.
   /// @param [in] CheckerName The *full name* of the checker. One may retrieve
   /// this from the checker object's field \c Name, or through \c
-  /// CheckerManager::getCurrentCheckName within the checker's registry
+  /// CheckerManager::getCurrentCheckerName within the checker's registry
   /// function.
   /// Checker options are retrieved in the following format:
   /// `-analyzer-config CheckerName:OptionName=Value.
@@ -365,7 +339,7 @@ public:
   /// If an option value is not provided, returns the given \p DefaultVal.
   /// @param [in] CheckerName The *full name* of the checker. One may retrieve
   /// this from the checker object's field \c Name, or through \c
-  /// CheckerManager::getCurrentCheckName within the checker's registry
+  /// CheckerManager::getCurrentCheckerName within the checker's registry
   /// function.
   /// Checker options are retrieved in the following format:
   /// `-analyzer-config CheckerName:OptionName=Value.
@@ -385,7 +359,7 @@ public:
   /// If an option value is not provided, returns the given \p DefaultVal.
   /// @param [in] CheckerName The *full name* of the checker. One may retrieve
   /// this from the checker object's field \c Name, or through \c
-  /// CheckerManager::getCurrentCheckName within the checker's registry
+  /// CheckerManager::getCurrentCheckerName within the checker's registry
   /// function.
   /// Checker options are retrieved in the following format:
   /// `-analyzer-config CheckerName:OptionName=Value.
@@ -439,6 +413,42 @@ inline UserModeKind AnalyzerOptions::getUserMode() const {
   return K.getValue();
 }
 
+inline std::vector<StringRef>
+AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
+  static const StringRef StaticAnalyzerCheckerNames[] = {
+#define GET_CHECKERS
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) FULLNAME,
+#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+#undef CHECKER
+#undef GET_CHECKERS
+  };
+  std::vector<StringRef> Checkers;
+  for (StringRef CheckerName : StaticAnalyzerCheckerNames) {
+    if (!CheckerName.startswith("debug.") &&
+        (IncludeExperimental || !CheckerName.startswith("alpha.")))
+      Checkers.push_back(CheckerName);
+  }
+  return Checkers;
+}
+
+inline std::vector<StringRef>
+AnalyzerOptions::getRegisteredPackages(bool IncludeExperimental) {
+  static const StringRef StaticAnalyzerPackageNames[] = {
+#define GET_PACKAGES
+#define PACKAGE(FULLNAME) FULLNAME,
+#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+#undef PACKAGE
+#undef GET_PACKAGES
+  };
+  std::vector<StringRef> Packages;
+  for (StringRef PackageName : StaticAnalyzerPackageNames) {
+    if (PackageName != "debug" &&
+        (IncludeExperimental || PackageName != "alpha"))
+      Packages.push_back(PackageName);
+  }
+  return Packages;
+}
+
 } // namespace clang
 
 #endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
index 019b434..e94b544 100644 (file)
@@ -621,7 +621,7 @@ public:
                        ArrayRef<SourceRange> Ranges = None,
                        ArrayRef<FixItHint> Fixits = None);
 
-  void EmitBasicReport(const Decl *DeclWithIssue, CheckName CheckName,
+  void EmitBasicReport(const Decl *DeclWithIssue, CheckerNameRef CheckerName,
                        StringRef BugName, StringRef BugCategory,
                        StringRef BugStr, PathDiagnosticLocation Loc,
                        ArrayRef<SourceRange> Ranges = None,
@@ -632,7 +632,7 @@ private:
 
   /// Returns a BugType that is associated with the given name and
   /// category.
-  BugType *getBugTypeForName(CheckName CheckName, StringRef name,
+  BugType *getBugTypeForName(CheckerNameRef CheckerName, StringRef name,
                              StringRef category);
 
   virtual BugReport *
index 324b531..237053d 100644 (file)
@@ -28,8 +28,8 @@ class ExprEngine;
 
 class BugType {
 private:
-  const CheckName Check;
-  const std::string Name;
+  const CheckerNameRef CheckerName;
+  const std::string Description;
   const std::string Category;
   const CheckerBase *Checker;
   bool SuppressOnSink;
@@ -37,28 +37,27 @@ private:
   virtual void anchor();
 
 public:
-  BugType(CheckName Check, StringRef Name, StringRef Cat,
-          bool SuppressOnSink=false)
-      : Check(Check), Name(Name), Category(Cat), Checker(nullptr),
-        SuppressOnSink(SuppressOnSink) {}
+  BugType(CheckerNameRef CheckerName, StringRef Name, StringRef Cat,
+          bool SuppressOnSink = false)
+      : CheckerName(CheckerName), Description(Name), Category(Cat),
+        Checker(nullptr), SuppressOnSink(SuppressOnSink) {}
   BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat,
-          bool SuppressOnSink=false)
-      : Check(Checker->getCheckName()), Name(Name), Category(Cat),
-        Checker(Checker), SuppressOnSink(SuppressOnSink) {}
+          bool SuppressOnSink = false)
+      : CheckerName(Checker->getCheckerName()), Description(Name),
+        Category(Cat), Checker(Checker), SuppressOnSink(SuppressOnSink) {}
   virtual ~BugType() = default;
 
-  StringRef getName() const { return Name; }
+  StringRef getDescription() const { return Description; }
   StringRef getCategory() const { return Category; }
-  StringRef getCheckName() const {
-    // FIXME: This is a workaround to ensure that the correct check name is used
-    // The check names are set after the constructors are run.
+  StringRef getCheckerName() const {
+    // FIXME: This is a workaround to ensure that the correct checerk name is
+    // used. The checker names are set after the constructors are run.
     // In case the BugType object is initialized in the checker's ctor
-    // the Check field will be empty. To circumvent this problem we use
+    // the CheckerName field will be empty. To circumvent this problem we use
     // CheckerBase whenever it is possible.
-    StringRef CheckName =
-        Checker ? Checker->getCheckName().getName() : Check.getName();
-    assert(!CheckName.empty() && "Check name is not set properly.");
-    return CheckName;
+    StringRef Ret = Checker ? Checker->getCheckerName() : CheckerName;
+    assert(!Ret.empty() && "Checker name is not set properly.");
+    return Ret;
   }
 
   /// isSuppressOnSink - Returns true if bug reports associated with this bug
@@ -71,8 +70,9 @@ class BuiltinBug : public BugType {
   const std::string desc;
   void anchor() override;
 public:
-  BuiltinBug(class CheckName check, const char *name, const char *description)
-      : BugType(check, name, categories::LogicError), desc(description) {}
+  BuiltinBug(class CheckerNameRef checker, const char *name,
+             const char *description)
+      : BugType(checker, name, categories::LogicError), desc(description) {}
 
   BuiltinBug(const CheckerBase *checker, const char *name,
              const char *description)
index d0fe15f..0c7acdb 100644 (file)
@@ -490,12 +490,12 @@ public:
 } // end eval namespace
 
 class CheckerBase : public ProgramPointTag {
-  CheckName Name;
+  CheckerNameRef Name;
   friend class ::clang::ento::CheckerManager;
 
 public:
   StringRef getTagDescription() const override;
-  CheckName getCheckName() const;
+  CheckerNameRef getCheckerName() const;
 
   /// See CheckerManager::runCheckersForPrintState.
   virtual void printState(raw_ostream &Out, ProgramStateRef State,
index 8eec7ed..38a9aaf 100644 (file)
@@ -90,19 +90,20 @@ enum PointerEscapeKind {
   PSK_EscapeOther
 };
 
-// This wrapper is used to ensure that only StringRefs originating from the
-// CheckerRegistry are used as check names. We want to make sure all check
-// name strings have a lifetime that keeps them alive at least until the path
-// diagnostics have been processed.
-class CheckName {
+/// This wrapper is used to ensure that only StringRefs originating from the
+/// CheckerRegistry are used as check names. We want to make sure all checker
+/// name strings have a lifetime that keeps them alive at least until the path
+/// diagnostics have been processed, since they are expected to be constexpr
+/// string literals (most likely generated by TblGen).
+class CheckerNameRef {
   friend class ::clang::ento::CheckerRegistry;
 
   StringRef Name;
 
-  explicit CheckName(StringRef Name) : Name(Name) {}
+  explicit CheckerNameRef(StringRef Name) : Name(Name) {}
 
 public:
-  CheckName() = default;
+  CheckerNameRef() = default;
 
   StringRef getName() const { return Name; }
   operator StringRef() const { return Name; }
@@ -118,7 +119,7 @@ class CheckerManager {
   ASTContext &Context;
   const LangOptions LangOpts;
   AnalyzerOptions &AOptions;
-  CheckName CurrentCheckName;
+  CheckerNameRef CurrentCheckerName;
 
 public:
   CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions)
@@ -126,8 +127,8 @@ public:
 
   ~CheckerManager();
 
-  void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
-  CheckName getCurrentCheckName() const { return CurrentCheckName; }
+  void setCurrentCheckerName(CheckerNameRef name) { CurrentCheckerName = name; }
+  CheckerNameRef getCurrentCheckerName() const { return CurrentCheckerName; }
 
   bool hasPathSensitiveCheckers() const;
 
@@ -163,7 +164,7 @@ public:
     assert(!ref && "Checker already registered, use getChecker!");
 
     CHECKER *checker = new CHECKER(std::forward<AT>(Args)...);
-    checker->Name = CurrentCheckName;
+    checker->Name = CurrentCheckerName;
     CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
     CHECKER::_register(checker, *this);
     ref = checker;
index eeb606e..2d09676 100644 (file)
@@ -666,7 +666,7 @@ public:
                                   const LocationContext *LCtx,
                                   ProgramStateRef State);
 
-  /// Evaluate a call, running pre- and post-call checks and allowing checkers
+  /// Evaluate a call, running pre- and post-call checkers and allowing checkers
   /// to be responsible for handling the evaluation of the call itself.
   void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
                 const CallEvent &Call);
index 33cb813..764cb8e 100644 (file)
@@ -117,11 +117,11 @@ void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current,
 PathDiagnostic::~PathDiagnostic() = default;
 
 PathDiagnostic::PathDiagnostic(
-    StringRef CheckName, const Decl *declWithIssue, StringRef bugtype,
+    StringRef CheckerName, const Decl *declWithIssue, StringRef bugtype,
     StringRef verboseDesc, StringRef shortDesc, StringRef category,
     PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique,
     std::unique_ptr<FilesToLineNumsMap> ExecutedLines)
-    : CheckName(CheckName), DeclWithIssue(declWithIssue),
+    : CheckerName(CheckerName), DeclWithIssue(declWithIssue),
       BugType(StripTrailingDots(bugtype)),
       VerboseDesc(StripTrailingDots(verboseDesc)),
       ShortDesc(StripTrailingDots(shortDesc)),
index abf8329..fd210d7 100644 (file)
@@ -37,7 +37,7 @@ void MainCallChecker::checkPreStmt(const CallExpr *CE,
       BT.reset(new BugType(this, "call to main", "example analyzer plugin"));
 
     auto report =
-        std::make_unique<PathSensitiveBugReport>(*BT, BT->getName(), N);
+        std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
     report->addRange(Callee->getSourceRange());
     C.emitReport(std::move(report));
   }
index f051573..3db0b88 100644 (file)
@@ -303,7 +303,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
         .Case("true", true)
         .Case("false", false)
         .Default(false);
-  Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks);
+  Opts.DisableAllCheckers = Args.hasArg(OPT_analyzer_disable_all_checks);
 
   Opts.visualizeExplodedGraphWithGraphViz =
     Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
index ba79064..503c451 100644 (file)
@@ -48,10 +48,10 @@ public:
     DefaultBool CheckCStringBufferOverlap;
     DefaultBool CheckCStringNotNullTerm;
 
-    CheckName CheckNameCStringNullArg;
-    CheckName CheckNameCStringOutOfBounds;
-    CheckName CheckNameCStringBufferOverlap;
-    CheckName CheckNameCStringNotNullTerm;
+    CheckerNameRef CheckNameCStringNullArg;
+    CheckerNameRef CheckNameCStringOutOfBounds;
+    CheckerNameRef CheckNameCStringBufferOverlap;
+    CheckerNameRef CheckNameCStringNotNullTerm;
   };
 
   CStringChecksFilter Filter;
@@ -2409,14 +2409,12 @@ bool ento::shouldRegisterCStringModeling(const LangOptions &LO) {
   void ento::register##name(CheckerManager &mgr) {                             \
     CStringChecker *checker = mgr.getChecker<CStringChecker>();                \
     checker->Filter.Check##name = true;                                        \
-    checker->Filter.CheckName##name = mgr.getCurrentCheckName();               \
+    checker->Filter.CheckName##name = mgr.getCurrentCheckerName();             \
   }                                                                            \
                                                                                \
-  bool ento::shouldRegister##name(const LangOptions &LO) {                     \
-    return true;                                                               \
-  }
+  bool ento::shouldRegister##name(const LangOptions &LO) { return true; }
 
-  REGISTER_CHECKER(CStringNullArg)
-  REGISTER_CHECKER(CStringOutOfBounds)
-  REGISTER_CHECKER(CStringBufferOverlap)
+REGISTER_CHECKER(CStringNullArg)
+REGISTER_CHECKER(CStringOutOfBounds)
+REGISTER_CHECKER(CStringBufferOverlap)
 REGISTER_CHECKER(CStringNotNullTerm)
index 325d2f8..2fcb765 100644 (file)
@@ -49,7 +49,7 @@ class CallAndMessageChecker
 
 public:
   DefaultBool Check_CallAndMessageUnInitRefArg;
-  CheckName CheckName_CallAndMessageUnInitRefArg;
+  CheckerNameRef CheckName_CallAndMessageUnInitRefArg;
 
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
   void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
@@ -95,7 +95,7 @@ void CallAndMessageChecker::emitBadCall(BugType *BT, CheckerContext &C,
   if (!N)
     return;
 
-  auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getName(), N);
+  auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
   if (BadE) {
     R->addRange(BadE->getSourceRange());
     if (BadE->isGLValue())
@@ -482,7 +482,7 @@ void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
       }
       assert(BT && "Unknown message kind.");
 
-      auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getName(), N);
+      auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
       const ObjCMessageExpr *ME = msg.getOriginExpr();
       R->addRange(ME->getReceiverRange());
 
@@ -612,7 +612,7 @@ bool ento::shouldRegisterCallAndMessageChecker(const LangOptions &LO) {
 void ento::registerCallAndMessageUnInitRefArg(CheckerManager &mgr) {
   CallAndMessageChecker *Checker = mgr.getChecker<CallAndMessageChecker>();
   Checker->Check_CallAndMessageUnInitRefArg = true;
-  Checker->CheckName_CallAndMessageUnInitRefArg = mgr.getCurrentCheckName();
+  Checker->CheckName_CallAndMessageUnInitRefArg = mgr.getCurrentCheckerName();
 }
 
 bool ento::shouldRegisterCallAndMessageUnInitRefArg(const LangOptions &LO) {
index 7f32b15..260a289 100644 (file)
@@ -50,19 +50,19 @@ struct ChecksFilter {
   DefaultBool check_FloatLoopCounter;
   DefaultBool check_UncheckedReturn;
 
-  CheckName checkName_bcmp;
-  CheckName checkName_bcopy;
-  CheckName checkName_bzero;
-  CheckName checkName_gets;
-  CheckName checkName_getpw;
-  CheckName checkName_mktemp;
-  CheckName checkName_mkstemp;
-  CheckName checkName_strcpy;
-  CheckName checkName_DeprecatedOrUnsafeBufferHandling;
-  CheckName checkName_rand;
-  CheckName checkName_vfork;
-  CheckName checkName_FloatLoopCounter;
-  CheckName checkName_UncheckedReturn;
+  CheckerNameRef checkName_bcmp;
+  CheckerNameRef checkName_bcopy;
+  CheckerNameRef checkName_bzero;
+  CheckerNameRef checkName_gets;
+  CheckerNameRef checkName_getpw;
+  CheckerNameRef checkName_mktemp;
+  CheckerNameRef checkName_mkstemp;
+  CheckerNameRef checkName_strcpy;
+  CheckerNameRef checkName_DeprecatedOrUnsafeBufferHandling;
+  CheckerNameRef checkName_rand;
+  CheckerNameRef checkName_vfork;
+  CheckerNameRef checkName_FloatLoopCounter;
+  CheckerNameRef checkName_UncheckedReturn;
 };
 
 class WalkAST : public StmtVisitor<WalkAST> {
@@ -1015,14 +1015,12 @@ bool ento::shouldRegisterSecuritySyntaxChecker(const LangOptions &LO) {
 
 #define REGISTER_CHECKER(name)                                                 \
   void ento::register##name(CheckerManager &mgr) {                             \
-    SecuritySyntaxChecker *checker =  mgr.getChecker<SecuritySyntaxChecker>(); \
+    SecuritySyntaxChecker *checker = mgr.getChecker<SecuritySyntaxChecker>();  \
     checker->filter.check_##name = true;                                       \
-    checker->filter.checkName_##name = mgr.getCurrentCheckName();              \
+    checker->filter.checkName_##name = mgr.getCurrentCheckerName();            \
   }                                                                            \
                                                                                \
-  bool ento::shouldRegister##name(const LangOptions &LO) {                     \
-    return true;                                                               \
-  }
+  bool ento::shouldRegister##name(const LangOptions &LO) { return true; }
 
 REGISTER_CHECKER(bcmp)
 REGISTER_CHECKER(bcopy)
index 8010c85..45c1984 100644 (file)
@@ -92,7 +92,7 @@ void DeleteWithNonVirtualDtorChecker::checkPreStmt(const CXXDeleteExpr *DE,
                          "Logic error"));
 
   ExplodedNode *N = C.generateNonFatalErrorNode();
-  auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getName(), N);
+  auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
 
   // Mark region of problematic base class for later use in the BugVisitor.
   R->markInteresting(BaseClassRegion);
index b32fa07..17c8139 100644 (file)
@@ -305,7 +305,7 @@ void ExprInspectionChecker::analyzerHashDump(const CallExpr *CE,
   const SourceManager &SM = C.getSourceManager();
   FullSourceLoc FL(CE->getArg(0)->getBeginLoc(), SM);
   std::string HashContent =
-      GetIssueString(SM, FL, getCheckName().getName(), "Category",
+      GetIssueString(SM, FL, getCheckerName().getName(), "Category",
                      C.getLocationContext()->getDecl(), Opts);
 
   reportBug(HashContent, C);
index b80f761..97ace68 100644 (file)
@@ -248,7 +248,7 @@ public:
   };
 
   DefaultBool ChecksEnabled[CK_NumCheckKinds];
-  CheckName CheckNames[CK_NumCheckKinds];
+  CheckerNameRef CheckNames[CK_NumCheckKinds];
 
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
   void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
@@ -2380,12 +2380,10 @@ bool ento::shouldRegisterIteratorModeling(const LangOptions &LO) {
     auto *checker = Mgr.getChecker<IteratorChecker>();                         \
     checker->ChecksEnabled[IteratorChecker::CK_##name] = true;                 \
     checker->CheckNames[IteratorChecker::CK_##name] =                          \
-        Mgr.getCurrentCheckName();                                             \
+        Mgr.getCurrentCheckerName();                                           \
   }                                                                            \
                                                                                \
-  bool ento::shouldRegister##name(const LangOptions &LO) {                     \
-    return true;                                                               \
-  }
+  bool ento::shouldRegister##name(const LangOptions &LO) { return true; }
 
 REGISTER_CHECKER(IteratorRangeChecker)
 REGISTER_CHECKER(MismatchedIteratorChecker)
index 2b75f3a..0d64fbd 100644 (file)
@@ -48,8 +48,8 @@ struct ChecksFilter {
   /// Check that all ivars are invalidated.
   DefaultBool check_InstanceVariableInvalidation;
 
-  CheckName checkName_MissingInvalidationMethod;
-  CheckName checkName_InstanceVariableInvalidation;
+  CheckerNameRef checkName_MissingInvalidationMethod;
+  CheckerNameRef checkName_InstanceVariableInvalidation;
 };
 
 class IvarInvalidationCheckerImpl {
@@ -199,7 +199,7 @@ class IvarInvalidationCheckerImpl {
                         const ObjCIvarDecl *IvarDecl,
                         const IvarToPropMapTy &IvarToPopertyMap);
 
-  void reportNoInvalidationMethod(CheckName CheckName,
+  void reportNoInvalidationMethod(CheckerNameRef CheckName,
                                   const ObjCIvarDecl *FirstIvarDecl,
                                   const IvarToPropMapTy &IvarToPopertyMap,
                                   const ObjCInterfaceDecl *InterfaceD,
@@ -526,7 +526,7 @@ visit(const ObjCImplementationDecl *ImplD) const {
 }
 
 void IvarInvalidationCheckerImpl::reportNoInvalidationMethod(
-    CheckName CheckName, const ObjCIvarDecl *FirstIvarDecl,
+    CheckerNameRef CheckName, const ObjCIvarDecl *FirstIvarDecl,
     const IvarToPropMapTy &IvarToPopertyMap,
     const ObjCInterfaceDecl *InterfaceD, bool MissingDeclaration) const {
   SmallString<128> sbuf;
@@ -748,12 +748,10 @@ bool ento::shouldRegisterIvarInvalidationModeling(const LangOptions &LO) {
     IvarInvalidationChecker *checker =                                         \
         mgr.getChecker<IvarInvalidationChecker>();                             \
     checker->Filter.check_##name = true;                                       \
-    checker->Filter.checkName_##name = mgr.getCurrentCheckName();              \
+    checker->Filter.checkName_##name = mgr.getCurrentCheckerName();            \
   }                                                                            \
                                                                                \
-  bool ento::shouldRegister##name(const LangOptions &LO) {                     \
-    return true;                                                               \
-  }
+  bool ento::shouldRegister##name(const LangOptions &LO) { return true; }
 
 REGISTER_CHECKER(InstanceVariableInvalidation)
 REGISTER_CHECKER(MissingInvalidationMethod)
index 260e61e..699b5c6 100644 (file)
@@ -208,7 +208,7 @@ public:
   DefaultBool IsOptimistic;
 
   DefaultBool ChecksEnabled[CK_NumCheckKinds];
-  CheckName CheckNames[CK_NumCheckKinds];
+  CheckerNameRef CheckNames[CK_NumCheckKinds];
 
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
@@ -3140,7 +3140,7 @@ void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) {
   MallocChecker *checker = mgr.getChecker<MallocChecker>();
   checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true;
   checker->CheckNames[MallocChecker::CK_InnerPointerChecker] =
-      mgr.getCurrentCheckName();
+      mgr.getCurrentCheckerName();
 }
 
 void ento::registerDynamicMemoryModeling(CheckerManager &mgr) {
@@ -3157,12 +3157,11 @@ bool ento::shouldRegisterDynamicMemoryModeling(const LangOptions &LO) {
   void ento::register##name(CheckerManager &mgr) {                             \
     MallocChecker *checker = mgr.getChecker<MallocChecker>();                  \
     checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
-    checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
+    checker->CheckNames[MallocChecker::CK_##name] =                            \
+        mgr.getCurrentCheckerName();                                           \
   }                                                                            \
                                                                                \
-  bool ento::shouldRegister##name(const LangOptions &LO) {                     \
-    return true;                                                               \
-  }
+  bool ento::shouldRegister##name(const LangOptions &LO) { return true; }
 
 REGISTER_CHECKER(MallocChecker)
 REGISTER_CHECKER(NewDeleteChecker)
index 2f46e81..4322ac2 100644 (file)
@@ -112,11 +112,11 @@ public:
     DefaultBool CheckNullablePassedToNonnull;
     DefaultBool CheckNullableReturnedFromNonnull;
 
-    CheckName CheckNameNullPassedToNonnull;
-    CheckName CheckNameNullReturnedFromNonnull;
-    CheckName CheckNameNullableDereferenced;
-    CheckName CheckNameNullablePassedToNonnull;
-    CheckName CheckNameNullableReturnedFromNonnull;
+    CheckerNameRef CheckNameNullPassedToNonnull;
+    CheckerNameRef CheckNameNullReturnedFromNonnull;
+    CheckerNameRef CheckNameNullableDereferenced;
+    CheckerNameRef CheckNameNullablePassedToNonnull;
+    CheckerNameRef CheckNameNullableReturnedFromNonnull;
   };
 
   NullabilityChecksFilter Filter;
@@ -1201,12 +1201,12 @@ bool ento::shouldRegisterNullabilityBase(const LangOptions &LO) {
   void ento::register##name##Checker(CheckerManager &mgr) {                    \
     NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>();        \
     checker->Filter.Check##name = true;                                        \
-    checker->Filter.CheckName##name = mgr.getCurrentCheckName();               \
+    checker->Filter.CheckName##name = mgr.getCurrentCheckerName();             \
     checker->NeedTracking = checker->NeedTracking || trackingRequired;         \
     checker->NoDiagnoseCallsToSystemHeaders =                                  \
         checker->NoDiagnoseCallsToSystemHeaders ||                             \
         mgr.getAnalyzerOptions().getCheckerBooleanOption(                      \
-                      checker, "NoDiagnoseCallsToSystemHeaders", true);        \
+            checker, "NoDiagnoseCallsToSystemHeaders", true);                  \
   }                                                                            \
                                                                                \
   bool ento::shouldRegister##name##Checker(const LangOptions &LO) {            \
index 0cd1c3f..2f075ea 100644 (file)
@@ -52,7 +52,7 @@ UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
     BT.reset(new BuiltinBug(this, "Array subscript is undefined"));
 
   // Generate a report for this bug.
-  auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getName(), N);
+  auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
   R->addRange(A->getIdx()->getSourceRange());
   bugreporter::trackExpressionValue(N, A->getIdx(), *R);
   C.emitReport(std::move(R));
index 0c83af1..a361051 100644 (file)
@@ -46,7 +46,7 @@ public:
   };
 
   DefaultBool ChecksEnabled[CK_NumCheckKinds];
-  CheckName CheckNames[CK_NumCheckKinds];
+  CheckerNameRef CheckNames[CK_NumCheckKinds];
 
   void checkPreStmt(const VAArgExpr *VAA, CheckerContext &C) const;
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
@@ -412,7 +412,8 @@ bool ento::shouldRegisterValistBase(const LangOptions &LO) {
   void ento::register##name##Checker(CheckerManager &mgr) {                    \
     ValistChecker *checker = mgr.getChecker<ValistChecker>();                  \
     checker->ChecksEnabled[ValistChecker::CK_##name] = true;                   \
-    checker->CheckNames[ValistChecker::CK_##name] = mgr.getCurrentCheckName(); \
+    checker->CheckNames[ValistChecker::CK_##name] =                            \
+        mgr.getCurrentCheckerName();                                           \
   }                                                                            \
                                                                                \
   bool ento::shouldRegister##name##Checker(const LangOptions &LO) {            \
index 3d0630e..12cee5f 100644 (file)
@@ -206,20 +206,20 @@ void ento::registerVirtualCallModeling(CheckerManager &Mgr) {
 
 void ento::registerPureVirtualCallChecker(CheckerManager &Mgr) {
   auto *Chk = Mgr.getChecker<VirtualCallChecker>();
-  Chk->BT_Pure = std::make_unique<BugType>(
-      Mgr.getCurrentCheckName(), "Pure virtual method call",
-      categories::CXXObjectLifecycle);
+  Chk->BT_Pure = std::make_unique<BugType>(Mgr.getCurrentCheckerName(),
+                                           "Pure virtual method call",
+                                           categories::CXXObjectLifecycle);
 }
 
 void ento::registerVirtualCallChecker(CheckerManager &Mgr) {
   auto *Chk = Mgr.getChecker<VirtualCallChecker>();
   if (!Mgr.getAnalyzerOptions().getCheckerBooleanOption(
-          Mgr.getCurrentCheckName(), "PureOnly")) {
+          Mgr.getCurrentCheckerName(), "PureOnly")) {
     Chk->BT_Impure = std::make_unique<BugType>(
-        Mgr.getCurrentCheckName(), "Unexpected loss of virtual dispatch",
+        Mgr.getCurrentCheckerName(), "Unexpected loss of virtual dispatch",
         categories::CXXObjectLifecycle);
     Chk->ShowFixIts = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
-        Mgr.getCurrentCheckName(), "ShowFixIts");
+        Mgr.getCurrentCheckerName(), "ShowFixIts");
   }
 }
 
index fed00ec..f689d8e 100644 (file)
@@ -1312,7 +1312,7 @@ static std::unique_ptr<PathDiagnostic>
 generateDiagnosticForBasicReport(const BasicBugReport *R) {
   const BugType &BT = R->getBugType();
   return std::make_unique<PathDiagnostic>(
-      BT.getCheckName(), R->getDeclWithIssue(), BT.getName(),
+      BT.getCheckerName(), R->getDeclWithIssue(), BT.getDescription(),
       R->getDescription(), R->getShortDescription(/*UseFallback=*/false),
       BT.getCategory(), R->getUniqueingLocation(), R->getUniqueingDecl(),
       std::make_unique<FilesToLineNumsMap>());
@@ -1323,7 +1323,7 @@ generateEmptyDiagnosticForReport(const PathSensitiveBugReport *R,
                                  const SourceManager &SM) {
   const BugType &BT = R->getBugType();
   return std::make_unique<PathDiagnostic>(
-      BT.getCheckName(), R->getDeclWithIssue(), BT.getName(),
+      BT.getCheckerName(), R->getDeclWithIssue(), BT.getDescription(),
       R->getDescription(), R->getShortDescription(/*UseFallback=*/false),
       BT.getCategory(), R->getUniqueingLocation(), R->getUniqueingDecl(),
       findExecutedLines(SM, R->getErrorNode()));
@@ -3235,12 +3235,12 @@ void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
                                   PathDiagnosticLocation Loc,
                                   ArrayRef<SourceRange> Ranges,
                                   ArrayRef<FixItHint> Fixits) {
-  EmitBasicReport(DeclWithIssue, Checker->getCheckName(), Name, Category, Str,
+  EmitBasicReport(DeclWithIssue, Checker->getCheckerName(), Name, Category, Str,
                   Loc, Ranges, Fixits);
 }
 
 void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
-                                  CheckName CheckName,
+                                  CheckerNameRef CheckName,
                                   StringRef name, StringRef category,
                                   StringRef str, PathDiagnosticLocation Loc,
                                   ArrayRef<SourceRange> Ranges,
@@ -3256,8 +3256,8 @@ void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
   emitReport(std::move(R));
 }
 
-BugType *BugReporter::getBugTypeForName(CheckName CheckName, StringRef name,
-                                        StringRef category) {
+BugType *BugReporter::getBugTypeForName(CheckerNameRef CheckName,
+                                        StringRef name, StringRef category) {
   SmallString<136> fullDesc;
   llvm::raw_svector_ostream(fullDesc) << CheckName.getName() << ":" << name
                                       << ":" << category;
index f4e6f90..bc1c896 100644 (file)
@@ -19,10 +19,10 @@ using namespace ento;
 int ImplicitNullDerefEvent::Tag;
 
 StringRef CheckerBase::getTagDescription() const {
-  return getCheckName().getName();
+  return getCheckerName().getName();
 }
 
-CheckName CheckerBase::getCheckName() const { return Name; }
+CheckerNameRef CheckerBase::getCheckerName() const { return Name; }
 
 CheckerProgramPointTag::CheckerProgramPointTag(StringRef CheckerName,
                                                StringRef Msg)
@@ -30,10 +30,10 @@ CheckerProgramPointTag::CheckerProgramPointTag(StringRef CheckerName,
 
 CheckerProgramPointTag::CheckerProgramPointTag(const CheckerBase *Checker,
                                                StringRef Msg)
-  : SimpleProgramPointTag(Checker->getCheckName().getName(), Msg) {}
+    : SimpleProgramPointTag(Checker->getCheckerName().getName(), Msg) {}
 
 raw_ostream& clang::ento::operator<<(raw_ostream &Out,
                                      const CheckerBase &Checker) {
-  Out << Checker.getCheckName().getName();
+  Out << Checker.getCheckerName().getName();
   return Out;
 }
index 27d5797..f676bd8 100644 (file)
@@ -748,7 +748,7 @@ void CheckerManager::runCheckersForPrintStateJson(raw_ostream &Out,
       continue;
 
     Indent(Out, Space, IsDot)
-        << "{ \"checker\": \"" << CT.second->getCheckName().getName()
+        << "{ \"checker\": \"" << CT.second->getCheckerName().getName()
         << "\", \"messages\": [" << NL;
     Indent(Out, InnerSpace, IsDot)
         << '\"' << TempBuf.str().trim() << '\"' << NL;
index 83303d7..058be98 100644 (file)
@@ -775,7 +775,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
   if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
     // Invalidate placement args.
     // FIXME: Once we figure out how we want allocators to work,
-    // we should be using the usual pre-/(default-)eval-/post-call checks here.
+    // we should be using the usual pre-/(default-)eval-/post-call checkers
+    // here.
     State = Call->invalidateRegions(blockCount);
     if (!State)
       return;
index d3df18a..a4918d7 100644 (file)
@@ -555,8 +555,9 @@ void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter &R,
     os  << "\n<!-- FUNCTIONNAME " <<  declName << " -->\n";
 
     os << "\n<!-- ISSUEHASHCONTENTOFLINEINCONTEXT "
-       << GetIssueHash(SMgr, L, D.getCheckName(), D.getBugType(), DeclWithIssue,
-                       PP.getLangOpts()) << " -->\n";
+       << GetIssueHash(SMgr, L, D.getCheckerName(), D.getBugType(),
+                       DeclWithIssue, PP.getLangOpts())
+       << " -->\n";
 
     os << "\n<!-- BUGLINE "
        << LineNumber
index be074db..3a3942a 100644 (file)
@@ -679,7 +679,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
     o << "   <key>type</key>";
     EmitString(o, D->getBugType()) << '\n';
     o << "   <key>check_name</key>";
-    EmitString(o, D->getCheckName()) << '\n';
+    EmitString(o, D->getCheckerName()) << '\n';
 
     o << "   <!-- This hash is experimental and going to change! -->\n";
     o << "   <key>issue_hash_content_of_line_in_context</key>";
@@ -689,7 +689,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
                                             : D->getLocation().asLocation()),
                     SM);
     const Decl *DeclWithIssue = D->getDeclWithIssue();
-    EmitString(o, GetIssueHash(SM, L, D->getCheckName(), D->getBugType(),
+    EmitString(o, GetIssueHash(SM, L, D->getCheckerName(), D->getBugType(),
                                DeclWithIssue, LangOpts))
         << '\n';
 
index 6d105fe..190ab7e 100644 (file)
@@ -242,7 +242,7 @@ static json::Object createResult(const PathDiagnostic &Diag,
   const PathPieces &Path = Diag.path.flatten(false);
   const SourceManager &SMgr = Path.front()->getLocation().getManager();
 
-  auto Iter = RuleMapping.find(Diag.getCheckName());
+  auto Iter = RuleMapping.find(Diag.getCheckerName());
   assert(Iter != RuleMapping.end() && "Rule ID is not in the array index map?");
 
   return json::Object{
@@ -254,7 +254,7 @@ static json::Object createResult(const PathDiagnostic &Diag,
            *Diag.getLocation().asLocation().getExpansionLoc().getFileEntry(),
            SMgr, Artifacts))}},
       {"ruleIndex", Iter->getValue()},
-      {"ruleId", Diag.getCheckName()}};
+      {"ruleId", Diag.getCheckerName()}};
 }
 
 static StringRef getRuleDescription(StringRef CheckName) {
@@ -280,7 +280,7 @@ static StringRef getRuleHelpURIStr(StringRef CheckName) {
 }
 
 static json::Object createRule(const PathDiagnostic &Diag) {
-  StringRef CheckName = Diag.getCheckName();
+  StringRef CheckName = Diag.getCheckerName();
   json::Object Ret{
       {"fullDescription", createMessage(getRuleDescription(CheckName))},
       {"name", CheckName},
@@ -299,7 +299,7 @@ static json::Array createRules(std::vector<const PathDiagnostic *> &Diags,
   llvm::StringSet<> Seen;
 
   llvm::for_each(Diags, [&](const PathDiagnostic *D) {
-    StringRef RuleID = D->getCheckName();
+    StringRef RuleID = D->getCheckerName();
     std::pair<llvm::StringSet<>::iterator, bool> P = Seen.insert(RuleID);
     if (P.second) {
       RuleMapping[RuleID] = Rules.size(); // Maps RuleID to an Array Index.
index a123bd6..8236907 100644 (file)
@@ -651,7 +651,7 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
 
   if (isBisonFile(C)) {
     reportAnalyzerProgress("Skipping bison-generated file\n");
-  } else if (Opts->DisableAllChecks) {
+  } else if (Opts->DisableAllCheckers) {
 
     // Don't analyze if the user explicitly asked for no checks to be performed
     // on this file.
index 322304b..e00fd97 100644 (file)
@@ -437,7 +437,7 @@ void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const {
 
   // Initialize the CheckerManager with all enabled checkers.
   for (const auto *Checker : enabledCheckers) {
-    CheckerMgr.setCurrentCheckName(CheckName(Checker->FullName));
+    CheckerMgr.setCurrentCheckerName(CheckerNameRef(Checker->FullName));
     Checker->Initialize(CheckerMgr);
   }
 }
index 4773852..4f504d2 100644 (file)
@@ -30,7 +30,7 @@ class TestAction : public ASTFrontendAction {
     void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
                               FilesMade *filesMade) override {
       for (const auto *PD : Diags)
-        Output << PD->getCheckName() << ":" << PD->getShortDescription();
+        Output << PD->getCheckerName() << ":" << PD->getShortDescription();
     }
 
     StringRef getName() const override { return "Test"; }