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