From 4edf0cb0e03e31d468979d0d7dec08bd9f4f8204 Mon Sep 17 00:00:00 2001 From: Abel Kocsis Date: Mon, 11 Nov 2019 17:26:44 +0100 Subject: [PATCH] [clang-tidy] Add bugprone-bad-signal-to-kill-thread checker and alias cert-pos44-c --- bad-signal-to-kill-thread.patch | 1133 ++++++++++++++++++++ .../bugprone/BadSignalToKillThreadCheck.cpp | 70 ++ .../bugprone/BadSignalToKillThreadCheck.h | 37 + .../clang-tidy/bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt | 1 + .../clang-tidy/cert/CERTTidyModule.cpp | 4 + clang-tools-extra/docs/ReleaseNotes.rst | 11 + .../checks/bugprone-bad-signal-to-kill-thread.rst | 16 + .../docs/clang-tidy/checks/cert-pos44-c.rst | 9 + clang-tools-extra/docs/clang-tidy/checks/list.rst | 2 + .../bugprone-bad-signal-to-kill-thread.cpp | 38 + 11 files changed, 1324 insertions(+) create mode 100644 bad-signal-to-kill-thread.patch create mode 100644 clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone-bad-signal-to-kill-thread.rst create mode 100644 clang-tools-extra/docs/clang-tidy/checks/cert-pos44-c.rst create mode 100644 clang-tools-extra/test/clang-tidy/bugprone-bad-signal-to-kill-thread.cpp diff --git a/bad-signal-to-kill-thread.patch b/bad-signal-to-kill-thread.patch new file mode 100644 index 0000000..39b1757 --- /dev/null +++ b/bad-signal-to-kill-thread.patch @@ -0,0 +1,1133 @@ +diff --git a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp +new file mode 100644 +index 00000000000..1f3dec497c0 +--- /dev/null ++++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp +@@ -0,0 +1,70 @@ ++//===--- BadSignalToKillThreadCheck.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 "BadSignalToKillThreadCheck.h" ++#include "clang/AST/ASTContext.h" ++#include "clang/ASTMatchers/ASTMatchFinder.h" ++ ++using namespace clang::ast_matchers; ++ ++namespace clang { ++namespace tidy { ++namespace bugprone { ++ ++void BadSignalToKillThreadCheck::registerMatchers(MatchFinder *Finder) { ++ Finder->addMatcher( ++ callExpr(allOf(callee(functionDecl(hasName("::pthread_kill"))), ++ argumentCountIs(2)), ++ hasArgument(1, integerLiteral().bind("integer-literal"))) ++ .bind("thread-kill"), ++ this); ++} ++ ++static Preprocessor *PP; ++ ++void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) { ++ const auto IsSigterm = [](const auto &KeyValue) -> bool { ++ return KeyValue.first->getName() == "SIGTERM"; ++ }; ++ const auto TryExpandAsInteger = ++ [](Preprocessor::macro_iterator It) -> Optional { ++ if (It == PP->macro_end()) ++ return llvm::None; ++ const MacroInfo *MI = PP->getMacroInfo(It->first); ++ const Token &T = MI->tokens().back(); ++ StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength()); ++ ++ llvm::APInt IntValue; ++ constexpr unsigned AutoSenseRadix = 0; ++ if (ValueStr.getAsInteger(AutoSenseRadix, IntValue)) ++ return llvm::None; ++ return IntValue.getZExtValue(); ++ }; ++ ++ const auto SigtermMacro = llvm::find_if(PP->macros(), IsSigterm); ++ ++ if (!SigtermValue && !(SigtermValue = TryExpandAsInteger(SigtermMacro))) ++ return; ++ ++ const auto *MatchedExpr = Result.Nodes.getNodeAs("thread-kill"); ++ const auto *MatchedIntLiteral = ++ Result.Nodes.getNodeAs("integer-literal"); ++ if (MatchedIntLiteral->getValue() == *SigtermValue) { ++ diag(MatchedExpr->getBeginLoc(), ++ "thread should not be terminated by raising the 'SIGTERM' signal"); ++ } ++} ++ ++void BadSignalToKillThreadCheck::registerPPCallbacks( ++ const SourceManager &SM, Preprocessor *pp, Preprocessor *ModuleExpanderPP) { ++ PP = pp; ++} ++ ++} // namespace bugprone ++} // namespace tidy ++} // namespace clang +diff --git a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h +new file mode 100644 +index 00000000000..d39fdec2e7d +--- /dev/null ++++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h +@@ -0,0 +1,37 @@ ++//===--- BadSignalToKillThreadCheck.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_BUGPRONE_BADSIGNALTOKILLTHREADCHECK_H ++#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BADSIGNALTOKILLTHREADCHECK_H ++ ++#include "../ClangTidyCheck.h" ++ ++namespace clang { ++namespace tidy { ++namespace bugprone { ++ ++/// Finds ``pthread_kill`` function calls when thread is terminated by ++/// ``SIGTERM`` signal. ++/// For the user-facing documentation see: ++/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-bad-signal-to-kill-thread.html ++class BadSignalToKillThreadCheck : public ClangTidyCheck { ++public: ++ BadSignalToKillThreadCheck(StringRef Name, ClangTidyContext *Context) ++ : ClangTidyCheck(Name, Context) {} ++ void registerMatchers(ast_matchers::MatchFinder *Finder) override; ++ void check(const ast_matchers::MatchFinder::MatchResult &Result) override; ++ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, ++ Preprocessor *ModuleExpanderPP) override; ++ Optional SigtermValue; ++}; ++ ++} // namespace bugprone ++} // namespace tidy ++} // namespace clang ++ ++#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BADSIGNALTOKILLTHREADCHECK_H +diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +index 074aa7a8ba6..99eff40ebf4 100644 +--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp ++++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +@@ -1,175 +1,178 @@ + //===--- BugproneTidyModule.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 "../cppcoreguidelines/NarrowingConversionsCheck.h" + #include "ArgumentCommentCheck.h" + #include "AssertSideEffectCheck.h" ++#include "BadSignalToKillThreadCheck.h" + #include "BoolPointerImplicitConversionCheck.h" + #include "BranchCloneCheck.h" + #include "CopyConstructorInitCheck.h" + #include "DanglingHandleCheck.h" + #include "DynamicStaticInitializersCheck.h" + #include "ExceptionEscapeCheck.h" + #include "FoldInitTypeCheck.h" + #include "ForwardDeclarationNamespaceCheck.h" + #include "ForwardingReferenceOverloadCheck.h" + #include "InaccurateEraseCheck.h" + #include "IncorrectRoundingsCheck.h" + #include "InfiniteLoopCheck.h" + #include "IntegerDivisionCheck.h" + #include "LambdaFunctionNameCheck.h" + #include "MacroParenthesesCheck.h" + #include "MacroRepeatedSideEffectsCheck.h" + #include "MisplacedOperatorInStrlenInAllocCheck.h" + #include "MisplacedWideningCastCheck.h" + #include "MoveForwardingReferenceCheck.h" + #include "MultipleStatementMacroCheck.h" + #include "NotNullTerminatedResultCheck.h" + #include "ParentVirtualCallCheck.h" + #include "PosixReturnCheck.h" + #include "SizeofContainerCheck.h" + #include "SizeofExpressionCheck.h" + #include "StringConstructorCheck.h" + #include "StringIntegerAssignmentCheck.h" + #include "StringLiteralWithEmbeddedNulCheck.h" + #include "SuspiciousEnumUsageCheck.h" + #include "SuspiciousMemsetUsageCheck.h" + #include "SuspiciousMissingCommaCheck.h" + #include "SuspiciousSemicolonCheck.h" + #include "SuspiciousStringCompareCheck.h" + #include "SwappedArgumentsCheck.h" + #include "TerminatingContinueCheck.h" + #include "ThrowKeywordMissingCheck.h" + #include "TooSmallLoopVariableCheck.h" + #include "UndefinedMemoryManipulationCheck.h" + #include "UndelegatedConstructorCheck.h" + #include "UnhandledSelfAssignmentCheck.h" + #include "UnusedRaiiCheck.h" + #include "UnusedReturnValueCheck.h" + #include "UseAfterMoveCheck.h" + #include "VirtualNearMissCheck.h" + + namespace clang { + namespace tidy { + namespace bugprone { + + class BugproneModule : public ClangTidyModule { + public: + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "bugprone-argument-comment"); + CheckFactories.registerCheck( + "bugprone-assert-side-effect"); ++ CheckFactories.registerCheck( ++ "bugprone-bad-signal-to-kill-thread"); + CheckFactories.registerCheck( + "bugprone-bool-pointer-implicit-conversion"); + CheckFactories.registerCheck( + "bugprone-branch-clone"); + CheckFactories.registerCheck( + "bugprone-copy-constructor-init"); + CheckFactories.registerCheck( + "bugprone-dangling-handle"); + CheckFactories.registerCheck( + "bugprone-dynamic-static-initializers"); + CheckFactories.registerCheck( + "bugprone-exception-escape"); + CheckFactories.registerCheck( + "bugprone-fold-init-type"); + CheckFactories.registerCheck( + "bugprone-forward-declaration-namespace"); + CheckFactories.registerCheck( + "bugprone-forwarding-reference-overload"); + CheckFactories.registerCheck( + "bugprone-inaccurate-erase"); + CheckFactories.registerCheck( + "bugprone-incorrect-roundings"); + CheckFactories.registerCheck( + "bugprone-infinite-loop"); + CheckFactories.registerCheck( + "bugprone-integer-division"); + CheckFactories.registerCheck( + "bugprone-lambda-function-name"); + CheckFactories.registerCheck( + "bugprone-macro-parentheses"); + CheckFactories.registerCheck( + "bugprone-macro-repeated-side-effects"); + CheckFactories.registerCheck( + "bugprone-misplaced-operator-in-strlen-in-alloc"); + CheckFactories.registerCheck( + "bugprone-misplaced-widening-cast"); + CheckFactories.registerCheck( + "bugprone-move-forwarding-reference"); + CheckFactories.registerCheck( + "bugprone-multiple-statement-macro"); + CheckFactories.registerCheck( + "bugprone-narrowing-conversions"); + CheckFactories.registerCheck( + "bugprone-not-null-terminated-result"); + CheckFactories.registerCheck( + "bugprone-parent-virtual-call"); + CheckFactories.registerCheck( + "bugprone-posix-return"); + CheckFactories.registerCheck( + "bugprone-sizeof-container"); + CheckFactories.registerCheck( + "bugprone-sizeof-expression"); + CheckFactories.registerCheck( + "bugprone-string-constructor"); + CheckFactories.registerCheck( + "bugprone-string-integer-assignment"); + CheckFactories.registerCheck( + "bugprone-string-literal-with-embedded-nul"); + CheckFactories.registerCheck( + "bugprone-suspicious-enum-usage"); + CheckFactories.registerCheck( + "bugprone-suspicious-memset-usage"); + CheckFactories.registerCheck( + "bugprone-suspicious-missing-comma"); + CheckFactories.registerCheck( + "bugprone-suspicious-semicolon"); + CheckFactories.registerCheck( + "bugprone-suspicious-string-compare"); + CheckFactories.registerCheck( + "bugprone-swapped-arguments"); + CheckFactories.registerCheck( + "bugprone-terminating-continue"); + CheckFactories.registerCheck( + "bugprone-throw-keyword-missing"); + CheckFactories.registerCheck( + "bugprone-too-small-loop-variable"); + CheckFactories.registerCheck( + "bugprone-undefined-memory-manipulation"); + CheckFactories.registerCheck( + "bugprone-undelegated-constructor"); + CheckFactories.registerCheck( + "bugprone-unhandled-self-assignment"); + CheckFactories.registerCheck( + "bugprone-unused-raii"); + CheckFactories.registerCheck( + "bugprone-unused-return-value"); + CheckFactories.registerCheck( + "bugprone-use-after-move"); + CheckFactories.registerCheck( + "bugprone-virtual-near-miss"); + } + }; + + } // namespace bugprone + + // Register the BugproneTidyModule using this statically initialized variable. + static ClangTidyModuleRegistry::Add + X("bugprone-module", "Adds checks for bugprone code constructs."); + + // This anchor is used to force the linker to link in the generated object file + // and thus register the BugproneModule. + volatile int BugproneModuleAnchorSource = 0; + + } // namespace tidy + } // namespace clang +diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +index ab3363f4373..4b499e68069 100644 +--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt ++++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +@@ -1,62 +1,63 @@ + set(LLVM_LINK_COMPONENTS support) + + add_clang_library(clangTidyBugproneModule + ArgumentCommentCheck.cpp + AssertSideEffectCheck.cpp ++ BadSignalToKillThreadCheck.cpp + BoolPointerImplicitConversionCheck.cpp + BranchCloneCheck.cpp + BugproneTidyModule.cpp + CopyConstructorInitCheck.cpp + DanglingHandleCheck.cpp + DynamicStaticInitializersCheck.cpp + ExceptionEscapeCheck.cpp + FoldInitTypeCheck.cpp + ForwardDeclarationNamespaceCheck.cpp + ForwardingReferenceOverloadCheck.cpp + InaccurateEraseCheck.cpp + IncorrectRoundingsCheck.cpp + InfiniteLoopCheck.cpp + IntegerDivisionCheck.cpp + LambdaFunctionNameCheck.cpp + MacroParenthesesCheck.cpp + MacroRepeatedSideEffectsCheck.cpp + MisplacedOperatorInStrlenInAllocCheck.cpp + MisplacedWideningCastCheck.cpp + MoveForwardingReferenceCheck.cpp + MultipleStatementMacroCheck.cpp + NotNullTerminatedResultCheck.cpp + ParentVirtualCallCheck.cpp + PosixReturnCheck.cpp + SizeofContainerCheck.cpp + SizeofExpressionCheck.cpp + StringConstructorCheck.cpp + StringIntegerAssignmentCheck.cpp + StringLiteralWithEmbeddedNulCheck.cpp + SuspiciousEnumUsageCheck.cpp + SuspiciousMemsetUsageCheck.cpp + SuspiciousMissingCommaCheck.cpp + SuspiciousSemicolonCheck.cpp + SuspiciousStringCompareCheck.cpp + SwappedArgumentsCheck.cpp + TerminatingContinueCheck.cpp + ThrowKeywordMissingCheck.cpp + TooSmallLoopVariableCheck.cpp + UndefinedMemoryManipulationCheck.cpp + UndelegatedConstructorCheck.cpp + UnhandledSelfAssignmentCheck.cpp + UnusedRaiiCheck.cpp + UnusedReturnValueCheck.cpp + UseAfterMoveCheck.cpp + VirtualNearMissCheck.cpp + + LINK_LIBS + clangAnalysis + clangAST + clangASTMatchers + clangBasic + clangLex + clangTidy + clangTidyCppCoreGuidelinesModule + clangTidyUtils + clangTooling + ) +diff --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp +index 341968b6fa6..23820446cd1 100644 +--- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp ++++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp +@@ -1,108 +1,112 @@ + //===--- CERTTidyModule.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 "../bugprone/UnhandledSelfAssignmentCheck.h" ++#include "../bugprone/BadSignalToKillThreadCheck.h" + #include "../google/UnnamedNamespaceInHeaderCheck.h" + #include "../misc/NewDeleteOverloadsCheck.h" + #include "../misc/NonCopyableObjects.h" + #include "../misc/StaticAssertCheck.h" + #include "../misc/ThrowByValueCatchByReferenceCheck.h" + #include "../performance/MoveConstructorInitCheck.h" + #include "../readability/UppercaseLiteralSuffixCheck.h" + #include "CommandProcessorCheck.h" + #include "DontModifyStdNamespaceCheck.h" + #include "FloatLoopCounter.h" + #include "LimitedRandomnessCheck.h" + #include "PostfixOperatorCheck.h" + #include "ProperlySeededRandomGeneratorCheck.h" + #include "SetLongJmpCheck.h" + #include "StaticObjectExceptionCheck.h" + #include "StrToNumCheck.h" + #include "ThrownExceptionTypeCheck.h" + #include "VariadicFunctionDefCheck.h" + + namespace clang { + namespace tidy { + namespace cert { + + class CERTModule : public ClangTidyModule { + public: + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + // C++ checkers + // DCL + CheckFactories.registerCheck( + "cert-dcl21-cpp"); + CheckFactories.registerCheck("cert-dcl50-cpp"); + CheckFactories.registerCheck( + "cert-dcl54-cpp"); + CheckFactories.registerCheck( + "cert-dcl58-cpp"); + CheckFactories.registerCheck( + "cert-dcl59-cpp"); + // OOP + CheckFactories.registerCheck( + "cert-oop11-cpp"); + CheckFactories.registerCheck( + "cert-oop54-cpp"); + // ERR + CheckFactories.registerCheck( + "cert-err09-cpp"); + CheckFactories.registerCheck("cert-err52-cpp"); + CheckFactories.registerCheck("cert-err58-cpp"); + CheckFactories.registerCheck("cert-err60-cpp"); + CheckFactories.registerCheck( + "cert-err61-cpp"); + // MSC + CheckFactories.registerCheck("cert-msc50-cpp"); + CheckFactories.registerCheck( + "cert-msc51-cpp"); + + // C checkers + // DCL + CheckFactories.registerCheck("cert-dcl03-c"); + CheckFactories.registerCheck( + "cert-dcl16-c"); + // ENV + CheckFactories.registerCheck("cert-env33-c"); + // FLP + CheckFactories.registerCheck("cert-flp30-c"); + // FIO + CheckFactories.registerCheck("cert-fio38-c"); + // ERR + CheckFactories.registerCheck("cert-err34-c"); + // MSC + CheckFactories.registerCheck("cert-msc30-c"); + CheckFactories.registerCheck( + "cert-msc32-c"); ++ // POS ++ CheckFactories.registerCheck( ++ "cert-pos44-c"); + } + + ClangTidyOptions getModuleOptions() override { + ClangTidyOptions Options; + ClangTidyOptions::OptionMap &Opts = Options.CheckOptions; + Opts["cert-dcl16-c.NewSuffixes"] = "L;LL;LU;LLU"; + Opts["cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField"] = "0"; + return Options; + } + }; + + } // namespace cert + + // Register the MiscTidyModule using this statically initialized variable. + static ClangTidyModuleRegistry::Add + X("cert-module", + "Adds lint checks corresponding to CERT secure coding guidelines."); + + // This anchor is used to force the linker to link in the generated object file + // and thus register the CERTModule. + volatile int CERTModuleAnchorSource = 0; + + } // namespace tidy + } // namespace clang +diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst +index fc5336602c8..a009f3e3107 100644 +--- a/clang-tools-extra/docs/ReleaseNotes.rst ++++ b/clang-tools-extra/docs/ReleaseNotes.rst +@@ -1,159 +1,170 @@ + ==================================================== + Extra Clang Tools 10.0.0 (In-Progress) Release Notes + ==================================================== + + .. contents:: + :local: + :depth: 3 + + Written by the `LLVM Team `_ + + .. warning:: + + These are in-progress notes for the upcoming Extra Clang Tools 10 release. + Release notes for previous releases can be found on + `the Download Page `_. + + Introduction + ============ + + This document contains the release notes for the Extra Clang Tools, part of the + Clang release 10.0.0. Here we describe the status of the Extra Clang Tools in + some detail, including major improvements from the previous release and new + feature work. All LLVM releases may be downloaded from the `LLVM releases web + site `_. + + For more information about Clang or LLVM, including information about + the latest release, please see the `Clang Web Site `_ or + the `LLVM Web Site `_. + + Note that if you are reading this file from a Subversion checkout or the + main Clang web page, this document applies to the *next* release, not + the current one. To see the release notes for a specific release, please + see the `releases page `_. + + What's New in Extra Clang Tools 10.0.0? + ======================================= + + Some of the major new features and improvements to Extra Clang Tools are listed + here. Generic improvements to Extra Clang Tools as a whole or to its underlying + infrastructure are described first, followed by tool-specific sections. + + Major New Features + ------------------ + + ... + + Improvements to clangd + ---------------------- + + The improvements are... + + Improvements to clang-doc + ------------------------- + + - :doc:`clang-doc ` now generates documentation in HTML format. + + Improvements to clang-query + --------------------------- + + The improvements are... + + Improvements to clang-rename + ---------------------------- + + The improvements are... + + Improvements to clang-tidy + -------------------------- + ++- New :doc:`bugprone-bad-signal-to-kill-thread ++ ` check. ++ ++ Finds ``pthread_kill`` function calls when a thread is terminated by ++ raising ``SIGTERM`` signal. ++ + - New :doc:`bugprone-dynamic-static-initializers + ` check. + + Finds instances where variables with static storage are initialized + dynamically in header files. + + - New :doc:`bugprone-infinite-loop + ` check. + + Finds obvious infinite loops (loops where the condition variable is not + changed at all). + + - New :doc:`bugprone-not-null-terminated-result + ` check + + Finds function calls where it is possible to cause a not null-terminated + result. Usually the proper length of a string is ``strlen(str) + 1`` or equal + length of this expression, because the null terminator needs an extra space. + Without the null terminator it can result in undefined behaviour when the + string is read. + ++- New alias :doc:`cert-pos44-cpp ++ ` to ++ :doc:`bugprone-bad-signal-to-kill-thread ++ ` was added. ++ + - New :doc:`cppcoreguidelines-init-variables + ` check. + + - New :doc:`darwin-dispatch-once-nonstatic + ` check. + + Finds declarations of ``dispatch_once_t`` variables without static or global + storage. + + - New :doc:`google-upgrade-googletest-case + ` check. + + Finds uses of deprecated Googletest APIs with names containing ``case`` and + replaces them with equivalent APIs with ``suite``. + + - New :doc:`linuxkernel-must-use-errs + ` check. + + Checks Linux kernel code to see if it uses the results from the functions in + ``linux/err.h``. + + - New :doc:`llvm-prefer-register-over-unsigned + ` check. + + Finds historical use of ``unsigned`` to hold vregs and physregs and rewrites + them to use ``Register`` + + - New :doc:`objc-missing-hash + ` check. + + Finds Objective-C implementations that implement ``-isEqual:`` without also + appropriately implementing ``-hash``. + + - Improved :doc:`bugprone-posix-return + ` check. + + Now also checks if any calls to ``pthread_*`` functions expect negative return + values. + + - The 'objc-avoid-spinlock' check was renamed to :doc:`darwin-avoid-spinlock + ` + + Improvements to include-fixer + ----------------------------- + + The improvements are... + + Improvements to clang-include-fixer + ----------------------------------- + + The improvements are... + + Improvements to modularize + -------------------------- + + The improvements are... + + Improvements to pp-trace + ------------------------ + + The improvements are... + + Clang-tidy visual studio plugin + ------------------------------- + + The clang-tidy-vs plugin has been removed from clang, as + it's no longer maintained. Users should migrate to + `Clang Power Tools `_ + instead. +diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone-bad-signal-to-kill-thread.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone-bad-signal-to-kill-thread.rst +new file mode 100644 +index 00000000000..05f5c936397 +--- /dev/null ++++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone-bad-signal-to-kill-thread.rst +@@ -0,0 +1,16 @@ ++.. title:: clang-tidy - bugprone-bad-signal-to-kill-thread ++ ++bugprone-bad-signal-to-kill-thread ++================================== ++ ++Finds ``pthread_kill`` function calls when a thread is terminated by ++raising ``SIGTERM`` signal and the signal kills the entire process, not ++just the individual thread. Use any signal except ``SIGTERM``. ++ ++.. code-block: c++ ++ ++ pthread_kill(thread, SIGTERM); ++ ++This check corresponds to the CERT C Coding Standard rule ++`POS44-C. Do not use signals to terminate threads ++`_. +diff --git a/clang-tools-extra/docs/clang-tidy/checks/cert-pos44-c.rst b/clang-tools-extra/docs/clang-tidy/checks/cert-pos44-c.rst +new file mode 100644 +index 00000000000..5bc48a685af +--- /dev/null ++++ b/clang-tools-extra/docs/clang-tidy/checks/cert-pos44-c.rst +@@ -0,0 +1,9 @@ ++.. title:: clang-tidy - cert-pos44-c ++.. meta:: ++ :http-equiv=refresh: 5;URL=bugprone-bad-signal-to-kill-thread.html ++ ++cert-pos44-c ++============ ++ ++The cert-pos44-c check is an alias, please see ++`bugprone-bad-signal-to-kill-thread `_ for more information. +diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst +index 5d3bedc603b..35567ca3fb0 100644 +--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst ++++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst +@@ -1,383 +1,385 @@ + .. title:: clang-tidy - Clang-Tidy Checks + + Clang-Tidy Checks + ================= + + .. toctree:: + + abseil-duration-addition + abseil-duration-comparison + abseil-duration-conversion-cast + abseil-duration-division + abseil-duration-factory-float + abseil-duration-factory-scale + abseil-duration-subtraction + abseil-duration-unnecessary-conversion + abseil-faster-strsplit-delimiter + abseil-no-internal-dependencies + abseil-no-namespace + abseil-redundant-strcat-calls + abseil-str-cat-append + abseil-string-find-startswith + abseil-time-comparison + abseil-time-subtraction + abseil-upgrade-duration-conversions + android-cloexec-accept + android-cloexec-accept4 + android-cloexec-creat + android-cloexec-dup + android-cloexec-epoll-create + android-cloexec-epoll-create1 + android-cloexec-fopen + android-cloexec-inotify-init + android-cloexec-inotify-init1 + android-cloexec-memfd-create + android-cloexec-open + android-cloexec-pipe + android-cloexec-pipe2 + android-cloexec-socket + android-comparison-in-temp-failure-retry + boost-use-to-string + bugprone-argument-comment + bugprone-assert-side-effect ++ bugprone-bad-signal-to-kill-thread + bugprone-bool-pointer-implicit-conversion + bugprone-branch-clone + bugprone-copy-constructor-init + bugprone-dangling-handle + bugprone-dynamic-static-initializers + bugprone-exception-escape + bugprone-fold-init-type + bugprone-forward-declaration-namespace + bugprone-forwarding-reference-overload + bugprone-inaccurate-erase + bugprone-incorrect-roundings + bugprone-infinite-loop + bugprone-integer-division + bugprone-lambda-function-name + bugprone-macro-parentheses + bugprone-macro-repeated-side-effects + bugprone-misplaced-operator-in-strlen-in-alloc + bugprone-misplaced-widening-cast + bugprone-move-forwarding-reference + bugprone-multiple-statement-macro + bugprone-not-null-terminated-result + bugprone-parent-virtual-call + bugprone-posix-return + bugprone-sizeof-container + bugprone-sizeof-expression + bugprone-string-constructor + bugprone-string-integer-assignment + bugprone-string-literal-with-embedded-nul + bugprone-suspicious-enum-usage + bugprone-suspicious-memset-usage + bugprone-suspicious-missing-comma + bugprone-suspicious-semicolon + bugprone-suspicious-string-compare + bugprone-swapped-arguments + bugprone-terminating-continue + bugprone-throw-keyword-missing + bugprone-too-small-loop-variable + bugprone-undefined-memory-manipulation + bugprone-undelegated-constructor + bugprone-unhandled-self-assignment + bugprone-unused-raii + bugprone-unused-return-value + bugprone-use-after-move + bugprone-virtual-near-miss + cert-dcl03-c (redirects to misc-static-assert) + cert-dcl16-c (redirects to readability-uppercase-literal-suffix) + cert-dcl21-cpp + cert-dcl50-cpp + cert-dcl54-cpp (redirects to misc-new-delete-overloads) + cert-dcl58-cpp + cert-dcl59-cpp (redirects to google-build-namespaces) + cert-env33-c + cert-err09-cpp (redirects to misc-throw-by-value-catch-by-reference) + cert-err34-c + cert-err52-cpp + cert-err58-cpp + cert-err60-cpp + cert-err61-cpp (redirects to misc-throw-by-value-catch-by-reference) + cert-fio38-c (redirects to misc-non-copyable-objects) + cert-flp30-c + cert-msc30-c (redirects to cert-msc50-cpp) + cert-msc32-c (redirects to cert-msc51-cpp) + cert-msc50-cpp + cert-msc51-cpp + cert-oop11-cpp (redirects to performance-move-constructor-init) + cert-oop54-cpp (redirects to bugprone-unhandled-self-assignment) ++ cert-pos44-c (redirects to bugprone-bad-signal-to-kill-thread) + clang-analyzer-core.CallAndMessage + clang-analyzer-core.DivideZero + clang-analyzer-core.DynamicTypePropagation + clang-analyzer-core.NonNullParamChecker + clang-analyzer-core.NullDereference + clang-analyzer-core.StackAddressEscape + clang-analyzer-core.UndefinedBinaryOperatorResult + clang-analyzer-core.VLASize + clang-analyzer-core.uninitialized.ArraySubscript + clang-analyzer-core.uninitialized.Assign + clang-analyzer-core.uninitialized.Branch + clang-analyzer-core.uninitialized.CapturedBlockVariable + clang-analyzer-core.uninitialized.UndefReturn + clang-analyzer-cplusplus.InnerPointer + clang-analyzer-cplusplus.Move + clang-analyzer-cplusplus.NewDelete + clang-analyzer-cplusplus.NewDeleteLeaks + clang-analyzer-deadcode.DeadStores + clang-analyzer-nullability.NullPassedToNonnull + clang-analyzer-nullability.NullReturnedFromNonnull + clang-analyzer-nullability.NullableDereferenced + clang-analyzer-nullability.NullablePassedToNonnull + clang-analyzer-nullability.NullableReturnedFromNonnull + clang-analyzer-optin.cplusplus.UninitializedObject + clang-analyzer-optin.cplusplus.VirtualCall + clang-analyzer-optin.mpi.MPI-Checker + clang-analyzer-optin.osx.OSObjectCStyleCast + clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker + clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker + clang-analyzer-optin.performance.GCDAntipattern + clang-analyzer-optin.performance.Padding + clang-analyzer-optin.portability.UnixAPI + clang-analyzer-osx.API + clang-analyzer-osx.MIG + clang-analyzer-osx.NumberObjectConversion + clang-analyzer-osx.OSObjectRetainCount + clang-analyzer-osx.ObjCProperty + clang-analyzer-osx.SecKeychainAPI + clang-analyzer-osx.cocoa.AtSync + clang-analyzer-osx.cocoa.AutoreleaseWrite + clang-analyzer-osx.cocoa.ClassRelease + clang-analyzer-osx.cocoa.Dealloc + clang-analyzer-osx.cocoa.IncompatibleMethodTypes + clang-analyzer-osx.cocoa.Loops + clang-analyzer-osx.cocoa.MissingSuperCall + clang-analyzer-osx.cocoa.NSAutoreleasePool + clang-analyzer-osx.cocoa.NSError + clang-analyzer-osx.cocoa.NilArg + clang-analyzer-osx.cocoa.NonNilReturnValue + clang-analyzer-osx.cocoa.ObjCGenerics + clang-analyzer-osx.cocoa.RetainCount + clang-analyzer-osx.cocoa.RunLoopAutoreleaseLeak + clang-analyzer-osx.cocoa.SelfInit + clang-analyzer-osx.cocoa.SuperDealloc + clang-analyzer-osx.cocoa.UnusedIvars + clang-analyzer-osx.cocoa.VariadicMethodTypes + clang-analyzer-osx.coreFoundation.CFError + clang-analyzer-osx.coreFoundation.CFNumber + clang-analyzer-osx.coreFoundation.CFRetainRelease + clang-analyzer-osx.coreFoundation.containers.OutOfBounds + clang-analyzer-osx.coreFoundation.containers.PointerSizedValues + clang-analyzer-security.FloatLoopCounter + clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling + clang-analyzer-security.insecureAPI.UncheckedReturn + clang-analyzer-security.insecureAPI.bcmp + clang-analyzer-security.insecureAPI.bcopy + clang-analyzer-security.insecureAPI.bzero + clang-analyzer-security.insecureAPI.getpw + clang-analyzer-security.insecureAPI.gets + clang-analyzer-security.insecureAPI.mkstemp + clang-analyzer-security.insecureAPI.mktemp + clang-analyzer-security.insecureAPI.rand + clang-analyzer-security.insecureAPI.strcpy + clang-analyzer-security.insecureAPI.vfork + clang-analyzer-unix.API + clang-analyzer-unix.Malloc + clang-analyzer-unix.MallocSizeof + clang-analyzer-unix.MismatchedDeallocator + clang-analyzer-unix.Vfork + clang-analyzer-unix.cstring.BadSizeArg + clang-analyzer-unix.cstring.NullArg + clang-analyzer-valist.CopyToSelf + clang-analyzer-valist.Uninitialized + clang-analyzer-valist.Unterminated + cppcoreguidelines-avoid-c-arrays (redirects to modernize-avoid-c-arrays) + cppcoreguidelines-avoid-goto + cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) + cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) + cppcoreguidelines-explicit-virtual-functions (redirects to modernize-use-override) + cppcoreguidelines-init-variables + cppcoreguidelines-interfaces-global-init + cppcoreguidelines-macro-usage + cppcoreguidelines-narrowing-conversions + cppcoreguidelines-no-malloc + cppcoreguidelines-non-private-member-variables-in-classes (redirects to misc-non-private-member-variables-in-classes) + cppcoreguidelines-owning-memory + cppcoreguidelines-pro-bounds-array-to-pointer-decay + cppcoreguidelines-pro-bounds-constant-array-index + cppcoreguidelines-pro-bounds-pointer-arithmetic + cppcoreguidelines-pro-type-const-cast + cppcoreguidelines-pro-type-cstyle-cast + cppcoreguidelines-pro-type-member-init + cppcoreguidelines-pro-type-reinterpret-cast + cppcoreguidelines-pro-type-static-cast-downcast + cppcoreguidelines-pro-type-union-access + cppcoreguidelines-pro-type-vararg + cppcoreguidelines-slicing + cppcoreguidelines-special-member-functions + darwin-avoid-spinlock + darwin-dispatch-once-nonstatic + fuchsia-default-arguments-calls + fuchsia-default-arguments-declarations + fuchsia-header-anon-namespaces (redirects to google-build-namespaces) + fuchsia-multiple-inheritance + fuchsia-overloaded-operator + fuchsia-restrict-system-includes + fuchsia-statically-constructed-objects + fuchsia-trailing-return + fuchsia-virtual-inheritance + google-build-explicit-make-pair + google-build-namespaces + google-build-using-namespace + google-default-arguments + google-explicit-constructor + google-global-names-in-headers + google-objc-avoid-nsobject-new + google-objc-avoid-throwing-exception + google-objc-function-naming + google-objc-global-variable-declaration + google-readability-avoid-underscore-in-googletest-name + google-readability-braces-around-statements (redirects to readability-braces-around-statements) + google-readability-casting + google-readability-function-size (redirects to readability-function-size) + google-readability-namespace-comments (redirects to llvm-namespace-comment) + google-readability-todo + google-runtime-int + google-runtime-operator + google-runtime-references + google-upgrade-googletest-case + hicpp-avoid-c-arrays (redirects to modernize-avoid-c-arrays) + hicpp-avoid-goto + hicpp-braces-around-statements (redirects to readability-braces-around-statements) + hicpp-deprecated-headers (redirects to modernize-deprecated-headers) + hicpp-exception-baseclass + hicpp-explicit-conversions (redirects to google-explicit-constructor) + hicpp-function-size (redirects to readability-function-size) + hicpp-invalid-access-moved (redirects to bugprone-use-after-move) + hicpp-member-init (redirects to cppcoreguidelines-pro-type-member-init) + hicpp-move-const-arg (redirects to performance-move-const-arg) + hicpp-multiway-paths-covered + hicpp-named-parameter (redirects to readability-named-parameter) + hicpp-new-delete-operators (redirects to misc-new-delete-overloads) + hicpp-no-array-decay (redirects to cppcoreguidelines-pro-bounds-array-to-pointer-decay) + hicpp-no-assembler + hicpp-no-malloc (redirects to cppcoreguidelines-no-malloc) + hicpp-noexcept-move (redirects to misc-noexcept-moveconstructor) + hicpp-signed-bitwise + hicpp-special-member-functions (redirects to cppcoreguidelines-special-member-functions) + hicpp-static-assert (redirects to misc-static-assert) + hicpp-undelegated-constructor (redirects to bugprone-undelegated-constructor) + hicpp-uppercase-literal-suffix (redirects to readability-uppercase-literal-suffix) + hicpp-use-auto (redirects to modernize-use-auto) + hicpp-use-emplace (redirects to modernize-use-emplace) + hicpp-use-equals-default (redirects to modernize-use-equals-default) + hicpp-use-equals-delete (redirects to modernize-use-equals-delete) + hicpp-use-noexcept (redirects to modernize-use-noexcept) + hicpp-use-nullptr (redirects to modernize-use-nullptr) + hicpp-use-override (redirects to modernize-use-override) + hicpp-vararg (redirects to cppcoreguidelines-pro-type-vararg) + linuxkernel-must-use-errs + llvm-header-guard + llvm-include-order + llvm-namespace-comment + llvm-prefer-isa-or-dyn-cast-in-conditionals + llvm-prefer-register-over-unsigned + llvm-twine-local + misc-definitions-in-headers + misc-misplaced-const + misc-new-delete-overloads + misc-non-copyable-objects + misc-non-private-member-variables-in-classes + misc-redundant-expression + misc-static-assert + misc-throw-by-value-catch-by-reference + misc-unconventional-assign-operator + misc-uniqueptr-reset-release + misc-unused-alias-decls + misc-unused-parameters + misc-unused-using-decls + modernize-avoid-bind + modernize-avoid-c-arrays + modernize-concat-nested-namespaces + modernize-deprecated-headers + modernize-deprecated-ios-base-aliases + modernize-loop-convert + modernize-make-shared + modernize-make-unique + modernize-pass-by-value + modernize-raw-string-literal + modernize-redundant-void-arg + modernize-replace-auto-ptr + modernize-replace-random-shuffle + modernize-return-braced-init-list + modernize-shrink-to-fit + modernize-unary-static-assert + modernize-use-auto + modernize-use-bool-literals + modernize-use-default-member-init + modernize-use-emplace + modernize-use-equals-default + modernize-use-equals-delete + modernize-use-nodiscard + modernize-use-noexcept + modernize-use-nullptr + modernize-use-override + modernize-use-trailing-return-type + modernize-use-transparent-functors + modernize-use-uncaught-exceptions + modernize-use-using + mpi-buffer-deref + mpi-type-mismatch + objc-avoid-nserror-init + objc-forbidden-subclassing + objc-missing-hash + objc-property-declaration + objc-super-self + openmp-exception-escape + openmp-use-default-none + performance-faster-string-find + performance-for-range-copy + performance-implicit-conversion-in-loop + performance-inefficient-algorithm + performance-inefficient-string-concatenation + performance-inefficient-vector-operation + performance-move-const-arg + performance-move-constructor-init + performance-noexcept-move-constructor + performance-type-promotion-in-math-fn + performance-unnecessary-copy-initialization + performance-unnecessary-value-param + portability-simd-intrinsics + readability-avoid-const-params-in-decls + readability-braces-around-statements + readability-const-return-type + readability-container-size-empty + readability-convert-member-functions-to-static + readability-delete-null-pointer + readability-deleted-default + readability-else-after-return + readability-function-size + readability-identifier-naming + readability-implicit-bool-conversion + readability-inconsistent-declaration-parameter-name + readability-isolate-declaration + readability-magic-numbers + readability-misleading-indentation + readability-misplaced-array-index + readability-named-parameter + readability-non-const-parameter + readability-redundant-control-flow + readability-redundant-declaration + readability-redundant-function-ptr-dereference + readability-redundant-member-init + readability-redundant-preprocessor + readability-redundant-smartptr-get + readability-redundant-string-cstr + readability-redundant-string-init + readability-simplify-boolean-expr + readability-simplify-subscript-expr + readability-static-accessed-through-instance + readability-static-definition-in-anonymous-namespace + readability-string-compare + readability-uniqueptr-delete-release + readability-uppercase-literal-suffix + zircon-temporary-objects +diff --git a/clang-tools-extra/test/clang-tidy/bugprone-bad-signal-to-kill-thread.cpp b/clang-tools-extra/test/clang-tidy/bugprone-bad-signal-to-kill-thread.cpp +new file mode 100644 +index 00000000000..5de2001e26b +--- /dev/null ++++ b/clang-tools-extra/test/clang-tidy/bugprone-bad-signal-to-kill-thread.cpp +@@ -0,0 +1,38 @@ ++// RUN: %check_clang_tidy %s bugprone-bad-signal-to-kill-thread %t ++ ++#define SIGTERM 15 ++#define SIGINT 2 ++using pthread_t = int; ++using pthread_attr_t = int; ++ ++int pthread_create(pthread_t *thread, const pthread_attr_t *attr, ++ void *(*start_routine)(void *), void *arg); ++ ++int pthread_kill(pthread_t thread, int sig); ++ ++int pthread_cancel(pthread_t thread); ++ ++void *test_func_return_a_pointer(void *foo); ++ ++int main() { ++ int result; ++ pthread_t thread; ++ ++ if ((result = pthread_create(&thread, nullptr, test_func_return_a_pointer, 0)) != 0) { ++ } ++ if ((result = pthread_kill(thread, SIGTERM)) != 0) { ++ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: thread should not be terminated by raising the 'SIGTERM' signal [bugprone-bad-signal-to-kill-thread] ++ } ++ ++ //compliant solution ++ if ((result = pthread_cancel(thread)) != 0) { ++ } ++ ++ if ((result = pthread_kill(thread, SIGINT)) != 0) { ++ } ++ if ((result = pthread_kill(thread, 0xF)) != 0) { ++ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: thread should not be terminated by raising the 'SIGTERM' signal [bugprone-bad-signal-to-kill-thread] ++ } ++ ++ return 0; ++} diff --git a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp new file mode 100644 index 0000000..1f3dec4 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp @@ -0,0 +1,70 @@ +//===--- BadSignalToKillThreadCheck.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 "BadSignalToKillThreadCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace bugprone { + +void BadSignalToKillThreadCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr(allOf(callee(functionDecl(hasName("::pthread_kill"))), + argumentCountIs(2)), + hasArgument(1, integerLiteral().bind("integer-literal"))) + .bind("thread-kill"), + this); +} + +static Preprocessor *PP; + +void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) { + const auto IsSigterm = [](const auto &KeyValue) -> bool { + return KeyValue.first->getName() == "SIGTERM"; + }; + const auto TryExpandAsInteger = + [](Preprocessor::macro_iterator It) -> Optional { + if (It == PP->macro_end()) + return llvm::None; + const MacroInfo *MI = PP->getMacroInfo(It->first); + const Token &T = MI->tokens().back(); + StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength()); + + llvm::APInt IntValue; + constexpr unsigned AutoSenseRadix = 0; + if (ValueStr.getAsInteger(AutoSenseRadix, IntValue)) + return llvm::None; + return IntValue.getZExtValue(); + }; + + const auto SigtermMacro = llvm::find_if(PP->macros(), IsSigterm); + + if (!SigtermValue && !(SigtermValue = TryExpandAsInteger(SigtermMacro))) + return; + + const auto *MatchedExpr = Result.Nodes.getNodeAs("thread-kill"); + const auto *MatchedIntLiteral = + Result.Nodes.getNodeAs("integer-literal"); + if (MatchedIntLiteral->getValue() == *SigtermValue) { + diag(MatchedExpr->getBeginLoc(), + "thread should not be terminated by raising the 'SIGTERM' signal"); + } +} + +void BadSignalToKillThreadCheck::registerPPCallbacks( + const SourceManager &SM, Preprocessor *pp, Preprocessor *ModuleExpanderPP) { + PP = pp; +} + +} // namespace bugprone +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h new file mode 100644 index 0000000..d39fdec --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.h @@ -0,0 +1,37 @@ +//===--- BadSignalToKillThreadCheck.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_BUGPRONE_BADSIGNALTOKILLTHREADCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BADSIGNALTOKILLTHREADCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang { +namespace tidy { +namespace bugprone { + +/// Finds ``pthread_kill`` function calls when thread is terminated by +/// ``SIGTERM`` signal. +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-bad-signal-to-kill-thread.html +class BadSignalToKillThreadCheck : public ClangTidyCheck { +public: + BadSignalToKillThreadCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, + Preprocessor *ModuleExpanderPP) override; + Optional SigtermValue; +}; + +} // namespace bugprone +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BADSIGNALTOKILLTHREADCHECK_H diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 074aa7a..99eff40 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -12,6 +12,7 @@ #include "../cppcoreguidelines/NarrowingConversionsCheck.h" #include "ArgumentCommentCheck.h" #include "AssertSideEffectCheck.h" +#include "BadSignalToKillThreadCheck.h" #include "BoolPointerImplicitConversionCheck.h" #include "BranchCloneCheck.h" #include "CopyConstructorInitCheck.h" @@ -68,6 +69,8 @@ public: "bugprone-argument-comment"); CheckFactories.registerCheck( "bugprone-assert-side-effect"); + CheckFactories.registerCheck( + "bugprone-bad-signal-to-kill-thread"); CheckFactories.registerCheck( "bugprone-bool-pointer-implicit-conversion"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index ab3363f..4b499e6 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyBugproneModule ArgumentCommentCheck.cpp AssertSideEffectCheck.cpp + BadSignalToKillThreadCheck.cpp BoolPointerImplicitConversionCheck.cpp BranchCloneCheck.cpp BugproneTidyModule.cpp diff --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp index 341968b..2382044 100644 --- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp @@ -10,6 +10,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "../bugprone/UnhandledSelfAssignmentCheck.h" +#include "../bugprone/BadSignalToKillThreadCheck.h" #include "../google/UnnamedNamespaceInHeaderCheck.h" #include "../misc/NewDeleteOverloadsCheck.h" #include "../misc/NonCopyableObjects.h" @@ -82,6 +83,9 @@ public: CheckFactories.registerCheck("cert-msc30-c"); CheckFactories.registerCheck( "cert-msc32-c"); + // POS + CheckFactories.registerCheck( + "cert-pos44-c"); } ClangTidyOptions getModuleOptions() override { diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 40b7aed..a94ee3d 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -67,6 +67,12 @@ The improvements are... Improvements to clang-tidy -------------------------- +- New :doc:`bugprone-bad-signal-to-kill-thread + ` check. + + Finds ``pthread_kill`` function calls when a thread is terminated by + raising ``SIGTERM`` signal. + - New :doc:`bugprone-dynamic-static-initializers ` check. @@ -88,6 +94,11 @@ Improvements to clang-tidy Without the null terminator it can result in undefined behaviour when the string is read. +- New alias :doc:`cert-pos44-cpp + ` to + :doc:`bugprone-bad-signal-to-kill-thread + ` was added. + - New :doc:`cppcoreguidelines-init-variables ` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone-bad-signal-to-kill-thread.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone-bad-signal-to-kill-thread.rst new file mode 100644 index 0000000..05f5c93 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone-bad-signal-to-kill-thread.rst @@ -0,0 +1,16 @@ +.. title:: clang-tidy - bugprone-bad-signal-to-kill-thread + +bugprone-bad-signal-to-kill-thread +================================== + +Finds ``pthread_kill`` function calls when a thread is terminated by +raising ``SIGTERM`` signal and the signal kills the entire process, not +just the individual thread. Use any signal except ``SIGTERM``. + +.. code-block: c++ + + pthread_kill(thread, SIGTERM); + +This check corresponds to the CERT C Coding Standard rule +`POS44-C. Do not use signals to terminate threads +`_. diff --git a/clang-tools-extra/docs/clang-tidy/checks/cert-pos44-c.rst b/clang-tools-extra/docs/clang-tidy/checks/cert-pos44-c.rst new file mode 100644 index 0000000..5bc48a6 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/cert-pos44-c.rst @@ -0,0 +1,9 @@ +.. title:: clang-tidy - cert-pos44-c +.. meta:: + :http-equiv=refresh: 5;URL=bugprone-bad-signal-to-kill-thread.html + +cert-pos44-c +============ + +The cert-pos44-c check is an alias, please see +`bugprone-bad-signal-to-kill-thread `_ for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index b499a84..9e6e347 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -39,6 +39,7 @@ Clang-Tidy Checks boost-use-to-string bugprone-argument-comment bugprone-assert-side-effect + bugprone-bad-signal-to-kill-thread bugprone-bool-pointer-implicit-conversion bugprone-branch-clone bugprone-copy-constructor-init @@ -105,6 +106,7 @@ Clang-Tidy Checks cert-msc51-cpp cert-oop11-cpp (redirects to performance-move-constructor-init) cert-oop54-cpp (redirects to bugprone-unhandled-self-assignment) + cert-pos44-c (redirects to bugprone-bad-signal-to-kill-thread) clang-analyzer-core.CallAndMessage (redirects to https://clang.llvm.org/docs/analyzer/checkers) clang-analyzer-core.DivideZero (redirects to https://clang.llvm.org/docs/analyzer/checkers) clang-analyzer-core.DynamicTypePropagation diff --git a/clang-tools-extra/test/clang-tidy/bugprone-bad-signal-to-kill-thread.cpp b/clang-tools-extra/test/clang-tidy/bugprone-bad-signal-to-kill-thread.cpp new file mode 100644 index 0000000..5de2001 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/bugprone-bad-signal-to-kill-thread.cpp @@ -0,0 +1,38 @@ +// RUN: %check_clang_tidy %s bugprone-bad-signal-to-kill-thread %t + +#define SIGTERM 15 +#define SIGINT 2 +using pthread_t = int; +using pthread_attr_t = int; + +int pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg); + +int pthread_kill(pthread_t thread, int sig); + +int pthread_cancel(pthread_t thread); + +void *test_func_return_a_pointer(void *foo); + +int main() { + int result; + pthread_t thread; + + if ((result = pthread_create(&thread, nullptr, test_func_return_a_pointer, 0)) != 0) { + } + if ((result = pthread_kill(thread, SIGTERM)) != 0) { + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: thread should not be terminated by raising the 'SIGTERM' signal [bugprone-bad-signal-to-kill-thread] + } + + //compliant solution + if ((result = pthread_cancel(thread)) != 0) { + } + + if ((result = pthread_kill(thread, SIGINT)) != 0) { + } + if ((result = pthread_kill(thread, 0xF)) != 0) { + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: thread should not be terminated by raising the 'SIGTERM' signal [bugprone-bad-signal-to-kill-thread] + } + + return 0; +} -- 2.7.4