tmroeder updated this revision to Diff 196150.
tmroeder added a comment.

Actually add the documentation in the release notes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59963/new/

https://reviews.llvm.org/D59963

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

Index: clang-tools-extra/test/clang-tidy/linuxkernel-must-check-errs.c
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/linuxkernel-must-check-errs.c
@@ -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: Unused result from error function ERR_PTR
+  PTR_ERR((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Unused result from error function PTR_ERR
+  IS_ERR((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Unused result from error function IS_ERR
+  ERR_CAST((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Unused result from error function ERR_CAST
+out:
+  PTR_ERR_OR_ZERO((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Unused result from error function PTR_ERR_OR_ZERO
+}
+
+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: Unused result from function f1, which returns an error value
+  f2();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Unused result from function f2, which returns an error value
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -175,6 +175,7 @@
    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
Index: clang-tools-extra/docs/clang-tidy/checks/linuxkernel-must-use-errs.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/linuxkernel-must-use-errs.rst
@@ -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();
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -142,6 +142,11 @@
   <clang-tidy/checks/modernize-use-override>` now supports `OverrideSpelling`
   and `FinalSpelling` options.
 
+- New :doc:`linuxkernel-must-use-errs
+  <clang-tidy/checks/linuxkernel-must-use-errs>` check.
+
+  Checks Linux Kernel code for misuse of important error functions.
+
 - New :doc:`openmp-exception-escape
   <clang-tidy/checks/openmp-exception-escape>` check.
 
Index: clang-tools-extra/clang-tidy/tool/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/tool/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/tool/CMakeLists.txt
@@ -26,6 +26,7 @@
   clangTidyFuchsiaModule
   clangTidyGoogleModule
   clangTidyHICPPModule
+  clangTidyLinuxKernelModule
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyModernizeModule
Index: clang-tools-extra/clang-tidy/plugin/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/plugin/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/plugin/CMakeLists.txt
@@ -17,6 +17,7 @@
   clangTidyFuchsiaModule
   clangTidyGoogleModule
   clangTidyHICPPModule
+  clangTidyLinuxKernelModule
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyModernizeModule
Index: clang-tools-extra/clang-tidy/linuxkernel/MustCheckErrsCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/linuxkernel/MustCheckErrsCheck.h
@@ -0,0 +1,44 @@
+//===--- 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 {
+
+/// Propagates __attribute__((warn_unused_result)) from a small set of kernel
+/// functions that are essential to check.
+///
+/// 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 punned into the
+/// same space. Even though these functions are marked with
+/// __attribute__((warn_unused_result)), that's not enough for them always to be
+/// checked.
+///
+/// TODO: propagate return values and force checking of unused values.
+///
+/// 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
Index: clang-tools-extra/clang-tidy/linuxkernel/MustCheckErrsCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/linuxkernel/MustCheckErrsCheck.cpp
@@ -0,0 +1,55 @@
+//===--- 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"
+#include <c++/8/bits/c++config.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 &&
+      MatchedCallExpr->hasUnusedResultAttr(*Result.Context)) {
+    diag(MatchedCallExpr->getExprLoc(), "Unused result from error function %0")
+        << MatchedCallExpr->getDirectCallee()->getNameAsString();
+  }
+
+  const CallExpr *MatchedTransitiveCallExpr =
+      Result.Nodes.getNodeAs<CallExpr>("transitive_call");
+  if (MatchedTransitiveCallExpr) {
+    diag(MatchedTransitiveCallExpr->getExprLoc(),
+         "Unused result from function %0, which returns an error value")
+        << MatchedTransitiveCallExpr->getDirectCallee()->getNameAsString();
+  }
+}
+
+} // namespace linuxkernel
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp
@@ -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
Index: clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt
@@ -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
+  )
Index: clang-tools-extra/clang-tidy/ClangTidyForceLinker.h
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyForceLinker.h
+++ clang-tools-extra/clang-tidy/ClangTidyForceLinker.h
@@ -35,6 +35,11 @@
 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 =
Index: clang-tools-extra/clang-tidy/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/CMakeLists.txt
@@ -44,6 +44,7 @@
 add_subdirectory(fuchsia)
 add_subdirectory(google)
 add_subdirectory(hicpp)
+add_subdirectory(linuxkernel)
 add_subdirectory(llvm)
 add_subdirectory(misc)
 add_subdirectory(modernize)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to