[clang-tools-extra] r367071 - [clang-tidy] Add a module for the Linux kernel.

Tom Roeder via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 25 15:32:50 PDT 2019


Author: tmroeder
Date: Thu Jul 25 15:32:50 2019
New Revision: 367071

URL: http://llvm.org/viewvc/llvm-project?rev=367071&view=rev
Log:
[clang-tidy] Add a module for the Linux kernel.

Summary:
Now that clang is going to be able to build the Linux kernel again on
x86, and we have gen_compile_commands.py upstream for generating
compile_commands.json, clang-tidy can be used on the Linux kernel
source.

To that end, this commit adds a new clang-tidy module to be used for
checks specific to Linux kernel source. The Linux kernel follows its own
style of C, and it will be useful to separate those checks into their
own module.

This also adds an initial check that makes sure that return values from
the kernel error functions like PTR_ERR and ERR_PTR are checked. It also
makes sure that any functions that directly return values from these
functions are checked.

Subscribers: xazax.hun, gribozavr, Eugene.Zelenko, lebedev.ri, mgorny, jdoerfert, cfe-commits

Tags: #clang, #clang-tools-extra

Reviewers: aaron.ballman, alexfh, hokein, JonasToth

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

Added:
    clang-tools-extra/trunk/clang-tidy/linuxkernel/
    clang-tools-extra/trunk/clang-tidy/linuxkernel/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp
    clang-tools-extra/trunk/clang-tidy/linuxkernel/MustCheckErrsCheck.cpp
    clang-tools-extra/trunk/clang-tidy/linuxkernel/MustCheckErrsCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/linuxkernel-must-use-errs.rst
    clang-tools-extra/trunk/test/clang-tidy/linuxkernel-must-check-errs.c
Modified:
    clang-tools-extra/trunk/clang-tidy/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/ClangTidyForceLinker.h
    clang-tools-extra/trunk/clang-tidy/plugin/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt
    clang-tools-extra/trunk/docs/ReleaseNotes.rst
    clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/CMakeLists.txt?rev=367071&r1=367070&r2=367071&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/CMakeLists.txt Thu Jul 25 15:32:50 2019
@@ -44,6 +44,7 @@ add_subdirectory(cppcoreguidelines)
 add_subdirectory(fuchsia)
 add_subdirectory(google)
 add_subdirectory(hicpp)
+add_subdirectory(linuxkernel)
 add_subdirectory(llvm)
 add_subdirectory(misc)
 add_subdirectory(modernize)

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyForceLinker.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyForceLinker.h?rev=367071&r1=367070&r2=367071&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyForceLinker.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyForceLinker.h Thu Jul 25 15:32:50 2019
@@ -35,6 +35,11 @@ extern volatile int BugproneModuleAnchor
 static int LLVM_ATTRIBUTE_UNUSED BugproneModuleAnchorDestination =
     BugproneModuleAnchorSource;
 
+// This anchor is used to force the linker to link the LinuxKernelModule.
+extern volatile int LinuxKernelModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED LinuxKernelModuleAnchorDestination =
+    LinuxKernelModuleAnchorSource;
+
 // This anchor is used to force the linker to link the LLVMModule.
 extern volatile int LLVMModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =

Added: clang-tools-extra/trunk/clang-tidy/linuxkernel/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/linuxkernel/CMakeLists.txt?rev=367071&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/linuxkernel/CMakeLists.txt (added)
+++ clang-tools-extra/trunk/clang-tidy/linuxkernel/CMakeLists.txt Thu Jul 25 15:32:50 2019
@@ -0,0 +1,14 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangTidyLinuxKernelModule
+  LinuxKernelTidyModule.cpp
+  MustCheckErrsCheck.cpp
+
+  LINK_LIBS
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangLex
+  clangTidy
+  clangTidyUtils
+  )

Added: clang-tools-extra/trunk/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp?rev=367071&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp Thu Jul 25 15:32:50 2019
@@ -0,0 +1,37 @@
+//===--- LinuxKernelTidyModule.cpp - clang-tidy----------------------------===//
+//
+// 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 "../ClangTidy.h"
+#include "../ClangTidyModule.h"
+#include "../ClangTidyModuleRegistry.h"
+#include "MustCheckErrsCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace linuxkernel {
+
+/// This module is for checks specific to the Linux kernel.
+class LinuxKernelModule : public ClangTidyModule {
+public:
+  void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<MustCheckErrsCheck>(
+        "linuxkernel-must-check-errs");
+  }
+};
+// Register the LinuxKernelTidyModule using this statically initialized
+// variable.
+static ClangTidyModuleRegistry::Add<LinuxKernelModule>
+    X("linux-module", "Adds checks specific to the Linux kernel.");
+} // namespace linuxkernel
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the LinuxKernelModule.
+volatile int LinuxKernelModuleAnchorSource = 0;
+
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/linuxkernel/MustCheckErrsCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/linuxkernel/MustCheckErrsCheck.cpp?rev=367071&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/linuxkernel/MustCheckErrsCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/linuxkernel/MustCheckErrsCheck.cpp Thu Jul 25 15:32:50 2019
@@ -0,0 +1,53 @@
+//===--- MustCheckErrsCheck.cpp - clang-tidy ------------------------------===//
+//
+// 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 "MustCheckErrsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace linuxkernel {
+
+void MustCheckErrsCheck::registerMatchers(MatchFinder *Finder) {
+  auto ErrFn =
+      functionDecl(hasAnyName("ERR_PTR", "PTR_ERR", "IS_ERR", "IS_ERR_OR_NULL",
+                              "ERR_CAST", "PTR_ERR_OR_ZERO"));
+  auto NonCheckingStmts = stmt(anyOf(compoundStmt(), labelStmt()));
+  Finder->addMatcher(
+      callExpr(callee(ErrFn), hasParent(NonCheckingStmts)).bind("call"),
+      this);
+
+  auto ReturnToCheck = returnStmt(hasReturnValue(callExpr(callee(ErrFn))));
+  auto ReturnsErrFn = functionDecl(hasDescendant(ReturnToCheck));
+  Finder->addMatcher(callExpr(callee(ReturnsErrFn), hasParent(NonCheckingStmts))
+                         .bind("transitive_call"),
+                     this);
+}
+
+void MustCheckErrsCheck::check(const MatchFinder::MatchResult &Result) {
+  const CallExpr *MatchedCallExpr = Result.Nodes.getNodeAs<CallExpr>("call");
+  if (MatchedCallExpr) {
+    diag(MatchedCallExpr->getExprLoc(), "result from function %0 is unused")
+        << MatchedCallExpr->getDirectCallee();
+  }
+
+  const CallExpr *MatchedTransitiveCallExpr =
+      Result.Nodes.getNodeAs<CallExpr>("transitive_call");
+  if (MatchedTransitiveCallExpr) {
+    diag(MatchedTransitiveCallExpr->getExprLoc(),
+         "result from function %0 is unused but represents an error value")
+        << MatchedTransitiveCallExpr->getDirectCallee();
+  }
+}
+
+} // namespace linuxkernel
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/linuxkernel/MustCheckErrsCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/linuxkernel/MustCheckErrsCheck.h?rev=367071&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/linuxkernel/MustCheckErrsCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/linuxkernel/MustCheckErrsCheck.h Thu Jul 25 15:32:50 2019
@@ -0,0 +1,43 @@
+//===--- MustCheckErrsCheck.h - clang-tidy ----------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LINUXKERNEL_MUSTCHECKERRSCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LINUXKERNEL_MUSTCHECKERRSCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace linuxkernel {
+
+/// Checks Linux kernel code to see if it uses the results from the functions in
+/// linux/err.h. Also checks to see if code uses the results from functions that
+/// directly return a value from one of these error functions.
+///
+/// This is important in the Linux kernel because ERR_PTR, PTR_ERR, IS_ERR,
+/// IS_ERR_OR_NULL, ERR_CAST, and PTR_ERR_OR_ZERO return values must be checked,
+/// since positive pointers and negative error codes are being used in the same
+/// context. These functions are marked with
+/// __attribute__((warn_unused_result)), but some kernel versions do not have
+/// this warning enabled for clang.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/linuxkernel-must-use-errs.html
+class MustCheckErrsCheck : public ClangTidyCheck {
+public:
+  MustCheckErrsCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace linuxkernel
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LINUXKERNEL_MUSTCHECKERRSCHECK_H

Modified: clang-tools-extra/trunk/clang-tidy/plugin/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/plugin/CMakeLists.txt?rev=367071&r1=367070&r2=367071&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/plugin/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/plugin/CMakeLists.txt Thu Jul 25 15:32:50 2019
@@ -17,6 +17,7 @@ add_clang_library(clangTidyPlugin
   clangTidyFuchsiaModule
   clangTidyGoogleModule
   clangTidyHICPPModule
+  clangTidyLinuxKernelModule
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyModernizeModule

Modified: clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt?rev=367071&r1=367070&r2=367071&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt Thu Jul 25 15:32:50 2019
@@ -26,6 +26,7 @@ target_link_libraries(clang-tidy
   clangTidyFuchsiaModule
   clangTidyGoogleModule
   clangTidyHICPPModule
+  clangTidyLinuxKernelModule
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyModernizeModule

Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=367071&r1=367070&r2=367071&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Thu Jul 25 15:32:50 2019
@@ -67,7 +67,19 @@ The improvements are...
 Improvements to clang-tidy
 --------------------------
 
-The improvements are...
+- New :doc:`linuxkernel-must-use-errs
+  <clang-tidy/checks/linuxkernel-must-use-errs>` check.
+
+  Checks Linux kernel code to see if it uses the results from the functions in
+  ``linux/err.h``. Also checks to see if code uses the results from functions that
+  directly return a value from one of these error functions.
+
+  This is important in the Linux kernel because ``ERR_PTR``, ``PTR_ERR``,
+  ``IS_ERR``, ``IS_ERR_OR_NULL``, ``ERR_CAST``, and ``PTR_ERR_OR_ZERO`` return
+  values must be checked, since positive pointers and negative error codes are
+  being used in the same context. These functions are marked with
+  ``__attribute__((warn_unused_result))``, but some kernel versions do not have
+  this warning enabled for clang.
 
 Improvements to include-fixer
 -----------------------------

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/linuxkernel-must-use-errs.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/linuxkernel-must-use-errs.rst?rev=367071&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/linuxkernel-must-use-errs.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/linuxkernel-must-use-errs.rst Thu Jul 25 15:32:50 2019
@@ -0,0 +1,26 @@
+.. title:: clang-tidy - linuxkernel-must-use-errs
+
+linuxkernel-must-use-errs
+=========================
+
+Checks for cases where the kernel error functions ``ERR_PTR``,
+``PTR_ERR``, ``IS_ERR``, ``IS_ERR_OR_NULL``, ``ERR_CAST``, and
+``PTR_ERR_OR_ZERO`` are called but the results are not used. These
+functions are marked with ``__attribute__((warn_unused_result))``, but
+the compiler warning for this attribute is not always enabled.
+
+This also checks for unused values returned by functions that return
+``ERR_PTR``.
+
+Examples:
+
+.. code-block:: c
+
+  /* Trivial unused call to an ERR function */
+  PTR_ERR_OR_ZERO(some_function_call());
+
+  /* A function that returns ERR_PTR. */
+  void *fn() { ERR_PTR(-EINVAL); }
+
+  /* An invalid use of fn. */
+  fn();

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=367071&r1=367070&r2=367071&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Thu Jul 25 15:32:50 2019
@@ -183,6 +183,7 @@ Clang-Tidy Checks
    hicpp-use-nullptr (redirects to modernize-use-nullptr) <hicpp-use-nullptr>
    hicpp-use-override (redirects to modernize-use-override) <hicpp-use-override>
    hicpp-vararg (redirects to cppcoreguidelines-pro-type-vararg) <hicpp-vararg>
+   linuxkernel-must-use-errs
    llvm-header-guard
    llvm-include-order
    llvm-namespace-comment

Added: clang-tools-extra/trunk/test/clang-tidy/linuxkernel-must-check-errs.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/linuxkernel-must-check-errs.c?rev=367071&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/linuxkernel-must-check-errs.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/linuxkernel-must-check-errs.c Thu Jul 25 15:32:50 2019
@@ -0,0 +1,43 @@
+// RUN: %check_clang_tidy %s linuxkernel-must-check-errs %t
+
+#define __must_check __attribute__((warn_unused_result))
+
+// Prototypes of the error functions.
+void * __must_check ERR_PTR(long error);
+long  __must_check PTR_ERR(const void *ptr);
+int  __must_check IS_ERR(const void *ptr);
+int  __must_check IS_ERR_OR_NULL(const void *ptr);
+void * __must_check ERR_CAST(const void *ptr);
+int  __must_check PTR_ERR_OR_ZERO(const void *ptr);
+
+void f() {
+  ERR_PTR(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'ERR_PTR' is unused
+  PTR_ERR((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'PTR_ERR' is unused
+  IS_ERR((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'IS_ERR' is unused
+  ERR_CAST((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'ERR_CAST' is unused
+out:
+  PTR_ERR_OR_ZERO((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'PTR_ERR_OR_ZERO' is unused
+}
+
+void *f1() {
+  return ERR_PTR(0);
+}
+
+long f2() {
+  if (IS_ERR((void *)0)) {
+    return PTR_ERR((void *)0);
+  }
+  return -1;
+}
+
+void f3() {
+  f1();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'f1' is unused but represents an error value
+  f2();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'f2' is unused but represents an error value
+}




More information about the cfe-commits mailing list