tmroeder updated this revision to Diff 196148.
tmroeder marked an inline comment as done.
tmroeder added a comment.
Updated with an initial check.
Verified that add_new_check.py works (that's how I added the check). Also added
some basic docs and a test.
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.
+
+ FIXME: add release notes.
+
- 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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits