alexfh created this revision.
alexfh added reviewers: klimek, ilya-biryukov.
Herald added a subscriber: xazax.hun.

This addresses https://bugs.llvm.org/show_bug.cgi?id=37467.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D46951

Files:
  clang-tidy/misc/UnusedParametersCheck.cpp
  clang-tidy/misc/UnusedParametersCheck.h
  docs/clang-tidy/checks/misc-unused-parameters.rst
  test/clang-tidy/misc-unused-parameters-strict.cpp
  test/clang-tidy/misc-unused-parameters.cpp

Index: test/clang-tidy/misc-unused-parameters.cpp
===================================================================
--- test/clang-tidy/misc-unused-parameters.cpp
+++ test/clang-tidy/misc-unused-parameters.cpp
@@ -222,5 +222,34 @@
   return Function<void(int, int)>();
 }
 
+namespace strict_mode_off {
 // Do not warn on empty function bodies.
 void f(int foo) {}
+class E {
+  int i;
+
+public:
+  E(int j) {}
+};
+class F {
+  int i;
+
+public:
+  // Constructor initializer counts as a non-empty body.
+  F(int j) : i() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
+// CHECK-FIXES: {{^}}  F(int  /*j*/) : i() {}{{$}}
+};
+
+class A {
+public:
+  A();
+  A(int);
+};
+class B : public A {
+public:
+  B(int i) : A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is unused
+// CHECK-FIXES: {{^}}  B(int  /*i*/) : A() {}{{$}}
+};
+} // namespace strict_mode_off
Index: test/clang-tidy/misc-unused-parameters-strict.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/misc-unused-parameters-strict.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s misc-unused-parameters %t -- \
+// RUN:   -config="{CheckOptions: [{key: StrictMode, value: 1}]}" --
+
+// Warn on empty function bodies in StrictMode.
+namespace strict_mode {
+void f(int foo) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'foo' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void f(int  /*foo*/) {}{{$}}
+class E {
+  int i;
+
+public:
+  E(int j) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
+// CHECK-FIXES: {{^}}  E(int  /*j*/) {}{{$}}
+};
+class F {
+  int i;
+
+public:
+  F(int j) : i() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
+// CHECK-FIXES: {{^}}  F(int  /*j*/) : i() {}{{$}}
+};
+}
Index: docs/clang-tidy/checks/misc-unused-parameters.rst
===================================================================
--- docs/clang-tidy/checks/misc-unused-parameters.rst
+++ docs/clang-tidy/checks/misc-unused-parameters.rst
@@ -3,24 +3,40 @@
 misc-unused-parameters
 ======================
 
-Finds unused parameters and fixes them, so that `-Wunused-parameter` can be
-turned on.
+Finds unused function parameters. Unused parameters may signal about a bug in
+the code (e.g. when a different parameter is used instead). The suggested fixes
+either comment parameter name out or remove the parameter completely, if all
+callers of the function are in the same translation unit and can be updated.
+
+The check is similar to the `-Wunused-parameter` compiler diagnostic and can be
+used to prepare a codebase to enabling of that diagnostic. By default the check
+is more permissive (see :option:`StrictMode`).
 
 .. code-block:: c++
 
-  void a(int i) {}
+  void a(int i) { /*some code that doesn't use `i`*/ }
 
   // becomes
 
-  void a(int  /*i*/) {}
-
+  void a(int  /*i*/) { /*some code that doesn't use `i`*/ }
 
 .. code-block:: c++
 
   static void staticFunctionA(int i);
-  static void staticFunctionA(int i) {}
+  static void staticFunctionA(int i) { /*some code that doesn't use `i`*/ }
 
   // becomes
 
   static void staticFunctionA()
-  static void staticFunctionA() {}
+  static void staticFunctionA() { /*some code that doesn't use `i`*/ }
+
+Options
+-------
+
+.. option:: StrictMode
+
+   When zero (default value), the check will ignore trivially unused parameters,
+   i.e. when the corresponding function has an empty body (and in case of
+   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 in.
Index: clang-tidy/misc/UnusedParametersCheck.h
===================================================================
--- clang-tidy/misc/UnusedParametersCheck.h
+++ clang-tidy/misc/UnusedParametersCheck.h
@@ -24,8 +24,10 @@
   ~UnusedParametersCheck();
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
 
 private:
+  const bool StrictMode;
   class IndexerVisitor;
   std::unique_ptr<IndexerVisitor> Indexer;
 
Index: clang-tidy/misc/UnusedParametersCheck.cpp
===================================================================
--- clang-tidy/misc/UnusedParametersCheck.cpp
+++ clang-tidy/misc/UnusedParametersCheck.cpp
@@ -29,11 +29,10 @@
 } // namespace
 
 void UnusedParametersCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(functionDecl(isDefinition(),
-                                  hasBody(stmt(hasDescendant(stmt()))),
-                                  hasAnyParameter(decl()))
-                         .bind("function"),
-                     this);
+  Finder->addMatcher(
+      functionDecl(isDefinition(), hasBody(stmt()), hasAnyParameter(decl()))
+          .bind("function"),
+      this);
 }
 
 template <typename T>
@@ -122,7 +121,12 @@
 
 UnusedParametersCheck::UnusedParametersCheck(StringRef Name,
                                              ClangTidyContext *Context)
-    : ClangTidyCheck(Name, Context) {}
+    : ClangTidyCheck(Name, Context),
+      StrictMode(Options.getLocalOrGlobal("StrictMode", 0) != 0) {}
+
+void UnusedParametersCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "StrictMode", StrictMode);
+}
 
 void UnusedParametersCheck::warnOnUnusedParameter(
     const MatchFinder::MatchResult &Result, const FunctionDecl *Function,
@@ -170,7 +174,13 @@
     if (Param->isUsed() || Param->isReferenced() || !Param->getDeclName() ||
         Param->hasAttr<UnusedAttr>())
       continue;
-    warnOnUnusedParameter(Result, Function, i);
+
+    // In non-strict mode ignore function definitions with empty bodies
+    // (constructor initializer counts for non-empty body).
+    if (StrictMode || llvm::distance(Function->getBody()->children()) > 0 ||
+        (isa<CXXConstructorDecl>(Function) &&
+         cast<CXXConstructorDecl>(Function)->getNumCtorInitializers() > 0))
+      warnOnUnusedParameter(Result, Function, i);
   }
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to