diff --git a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.h b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.h --- a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.h +++ b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.h @@ -25,6 +25,7 @@ private: const bool StrictMode; + const bool IgnoreVirtual; class IndexerVisitor; std::unique_ptr Indexer; diff --git a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp --- a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp @@ -123,10 +123,12 @@ UnusedParametersCheck::UnusedParametersCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - StrictMode(Options.getLocalOrGlobal("StrictMode", false)) {} + StrictMode(Options.getLocalOrGlobal("StrictMode", false)), + IgnoreVirtual(Options.get("IgnoreVirtual", false)) {} void UnusedParametersCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "StrictMode", StrictMode); + Options.store(Opts, "IgnoreVirtual", IgnoreVirtual); } void UnusedParametersCheck::warnOnUnusedParameter( @@ -176,9 +178,12 @@ const auto *Function = Result.Nodes.getNodeAs("function"); if (!Function->hasWrittenPrototype() || Function->isTemplateInstantiation()) return; - if (const auto *Method = dyn_cast(Function)) + if (const auto *Method = dyn_cast(Function)) { + if (IgnoreVirtual && Method->isVirtual()) + return; if (Method->isLambdaStaticInvoker()) return; + } for (unsigned I = 0, E = Function->getNumParams(); I != E; ++I) { const auto *Param = Function->getParamDecl(I); if (Param->isUsed() || Param->isReferenced() || !Param->getDeclName() || diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -220,6 +220,10 @@ ` to avoid warning on declarations inside anonymous namespaces. +- Improved :doc:`misc-unused-parameters + ` check with new `IgnoreVirtual` + option to optionally ignore virtual methods. + - Deprecated check-local options `HeaderFileExtensions` in :doc:`misc-unused-using-decls ` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/unused-parameters.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/unused-parameters.rst --- a/clang-tools-extra/docs/clang-tidy/checks/misc/unused-parameters.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/unused-parameters.rst @@ -40,3 +40,8 @@ constructors - no constructor initializers). When the function body is empty, an unused parameter is unlikely to be unnoticed by a human reader, and there's basically no place for a bug to hide. + +.. option:: IgnoreVirtual + + Determines whether virtual method parameters should be inspected. + Set to `true` to ignore them. Default is `false`. diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters-virtual.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters-virtual.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters-virtual.cpp @@ -0,0 +1,20 @@ +// RUN: %check_clang_tidy %s misc-unused-parameters %t -- \ +// RUN: -config="{CheckOptions: [{key: misc-unused-parameters.IgnoreVirtual, value: true}]}" -- + +struct Base { + int f(int foo) { + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: parameter 'foo' is unused [misc-unused-parameters] + // CHECK-FIXES: int f(int /*foo*/) { + return 5; + } + + virtual int f2(int foo) { + return 5; + } +}; + +struct Derived : Base { + int f2(int foo) override { + return 5; + } +};