Index: clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp =================================================================== --- clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -38,6 +38,7 @@ #include "ParentVirtualCallCheck.h" #include "PosixReturnCheck.h" #include "ReservedIdentifierCheck.h" +#include "SignalInMultithreadedProgramCheck.h" #include "SignedCharMisuseCheck.h" #include "SizeofContainerCheck.h" #include "SizeofExpressionCheck.h" @@ -126,6 +127,8 @@ "bugprone-posix-return"); CheckFactories.registerCheck( "bugprone-reserved-identifier"); + CheckFactories.registerCheck( + "bugprone-signal-in-multithreaded-program"); CheckFactories.registerCheck( "bugprone-signed-char-misuse"); CheckFactories.registerCheck( Index: clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt =================================================================== --- clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -30,6 +30,7 @@ ParentVirtualCallCheck.cpp PosixReturnCheck.cpp ReservedIdentifierCheck.cpp + SignalInMultithreadedProgramCheck.cpp SignedCharMisuseCheck.cpp SizeofContainerCheck.cpp SizeofExpressionCheck.cpp Index: clang-tools-extra/clang-tidy/bugprone/SignalInMultithreadedProgramCheck.h =================================================================== --- /dev/null +++ clang-tools-extra/clang-tidy/bugprone/SignalInMultithreadedProgramCheck.h @@ -0,0 +1,38 @@ +//===--- SignalInMultithreadedProgramCheck.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_SIGNALINMULTITHREADEDPROGRAMCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SIGNALINMULTITHREADEDPROGRAMCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang { +namespace tidy { +namespace bugprone { + +/// Finds ``signal`` function calls when the program is multithreaded. It +/// founds a program multithreaded when it finds at least one function call +/// of the following: ``thrd_create``, ``std::thread``, ``boost::thread``, +/// ``dlib::thread_function``, ``dlib::thread_pool``, +/// ``dlib::default_thread_pool``, ``pthread_t``. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-signal-in-multithreaded-program.html +class SignalInMultithreadedProgramCheck : public ClangTidyCheck { +public: + SignalInMultithreadedProgramCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace bugprone +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SIGNALINMULTITHREADEDPROGRAMCHECK_H Index: clang-tools-extra/clang-tidy/bugprone/SignalInMultithreadedProgramCheck.cpp =================================================================== --- /dev/null +++ clang-tools-extra/clang-tidy/bugprone/SignalInMultithreadedProgramCheck.cpp @@ -0,0 +1,47 @@ +//===--- SignalInMultithreadedProgramCheck.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 "SignalInMultithreadedProgramCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace bugprone { + +void SignalInMultithreadedProgramCheck::registerMatchers(MatchFinder *Finder) { + + auto signalCall = + callExpr( + ignoringImpCasts(hasDescendant(declRefExpr(hasDeclaration( + functionDecl(allOf(hasName("signal"), parameterCountIs(2), + hasParameter(0, hasType(isInteger()))))))))) + .bind("signal"); + + auto threadCall = callExpr(ignoringImpCasts( + hasDescendant(declRefExpr(hasDeclaration(functionDecl(hasAnyName( + "thrd_create", "::thread", "boost::thread", "dlib::thread_function", + "dlib::thread_pool", "dlib::default_thread_pool", "pthread_t"))))))); + + Finder->addMatcher(translationUnitDecl(allOf(hasDescendant(signalCall), + hasDescendant(threadCall))), + this); +} + +void SignalInMultithreadedProgramCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *MatchedSignal = Result.Nodes.getNodeAs("signal"); + diag(MatchedSignal->getExprLoc(), + "singal function should not be called in a multithreaded program"); +} + +} // namespace bugprone +} // namespace tidy +} // namespace clang Index: clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp =================================================================== --- clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp +++ clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModuleRegistry.h" #include "../bugprone/BadSignalToKillThreadCheck.h" #include "../bugprone/ReservedIdentifierCheck.h" +#include "../bugprone/SignalInMultithreadedProgramCheck.h" #include "../bugprone/UnhandledSelfAssignmentCheck.h" #include "../google/UnnamedNamespaceInHeaderCheck.h" #include "../misc/NewDeleteOverloadsCheck.h" @@ -80,6 +81,8 @@ "cert-oop58-cpp"); // C checkers + // CON + CheckFactories.registerCheck("cert-con37-c"); // DCL CheckFactories.registerCheck("cert-dcl03-c"); CheckFactories.registerCheck( Index: clang-tools-extra/docs/ReleaseNotes.rst =================================================================== --- clang-tools-extra/docs/ReleaseNotes.rst +++ clang-tools-extra/docs/ReleaseNotes.rst @@ -82,6 +82,15 @@ Checks for usages of identifiers reserved for use by the implementation. +- New :doc:`bugprone-signal-in-multithreaded-program + ` check. + + Finds ``signal`` function calls when the program is multithreaded. It + founds a program multithreaded when it finds at least one function call + of the following: ``thrd_create``, ``std::thread``, ``boost::thread``, + ``dlib::thread_function``, ``dlib::thread_pool``, + ``dlib::default_thread_pool``, ``pthread_t``. + - New :doc:`cert-oop57-cpp ` check. @@ -100,6 +109,10 @@ New check aliases ^^^^^^^^^^^^^^^^^ +- New alias :doc:`cert-con37-c + ` to + :doc:`bugprone-signal-in-multithreaded-program + ` was added. - New alias :doc:`cert-dcl37-c ` to Index: clang-tools-extra/docs/clang-tidy/checks/bugprone-signal-in-multithreaded-program.rst =================================================================== --- /dev/null +++ clang-tools-extra/docs/clang-tidy/checks/bugprone-signal-in-multithreaded-program.rst @@ -0,0 +1,19 @@ +.. title:: clang-tidy - bugprone-signal-in-multithreaded-program + +bugprone-signal-in-multithreaded-program +======================================== + +Finds ``signal`` function calls when the program is multithreaded. It founds a +program multithreaded when it finds at least one function call of the +following: ``thrd_create``, ``std::thread``, ``boost::thread``, +``dlib::thread_function``, ``dlib::thread_pool``, +``dlib::default_thread_pool``, ``pthread_t``. + +.. code-block: c + + signal(SIGUSR1, handler); + thrd_t tid; + +This check corresponds to the CERT C++ Coding Standard rule +`CON37-C. Do not call signal() in a multithreaded program +`_. Index: clang-tools-extra/docs/clang-tidy/checks/cert-con37-c.rst =================================================================== --- /dev/null +++ clang-tools-extra/docs/clang-tidy/checks/cert-con37-c.rst @@ -0,0 +1,10 @@ +.. title:: clang-tidy - cert-con37-c +.. meta:: + :http-equiv=refresh: 5;URL=bugprone-signal-in-multithreaded-program.html + +cert-con37-c +============ + +The cert-con37-c check is an alias, please see +`bugprone-signal-in-multithreaded-program `_ +for more information. 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 @@ -73,6 +73,7 @@ `bugprone-parent-virtual-call `_, "Yes" `bugprone-posix-return `_, "Yes" `bugprone-reserved-identifier `_, "Yes" + `bugprone-signal-in-multithreaded-program `_, `bugprone-signed-char-misuse `_, `bugprone-sizeof-container `_, `bugprone-sizeof-expression `_, @@ -95,6 +96,7 @@ `bugprone-unused-return-value `_, `bugprone-use-after-move `_, `bugprone-virtual-near-miss `_, "Yes" + `cert-con37-c `_, `cert-dcl21-cpp `_, `cert-dcl50-cpp `_, `cert-dcl58-cpp `_, Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-in-multithreaded-program.cpp =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-in-multithreaded-program.cpp @@ -0,0 +1,36 @@ +// RUN: %check_clang_tidy %s bugprone-signal-in-multithreaded-program %t + +typedef unsigned long int thrd_t; +typedef int (*thrd_start_t)(void *); +typedef int sig_atomic_t; +#define SIGUSR1 30 +#define NULL 0 + +void (*signal(int sig, void (*handler)(int)))(int); + +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { return 0; }; +enum { + thrd_success = 0, +}; + +volatile sig_atomic_t flag = 0; + +void handler(int signum) { + flag = 1; +} + +int func(void *data) { + while (!flag) { + } + return 0; +} + +int main(void) { + signal(SIGUSR1, handler); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: singal function should not be called in a multithreaded program [bugprone-signal-in-multithreaded-program] + thrd_t tid; + + if (thrd_success != thrd_create(&tid, func, NULL)) { + } + return 0; +}