[clang-tools-extra] 2534041 - Revert rGa772f775a2ba401e95a0bbe73deb6300f1dc12c0 "[clang-tidy] Support C++14 in bugprone-signal-handler."

Simon Pilgrim via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 10 07:25:19 PDT 2022


Author: Simon Pilgrim
Date: 2022-08-10T15:25:04+01:00
New Revision: 25340410c9a574d438b8868630fc8a9297d03dd7

URL: https://github.com/llvm/llvm-project/commit/25340410c9a574d438b8868630fc8a9297d03dd7
DIFF: https://github.com/llvm/llvm-project/commit/25340410c9a574d438b8868630fc8a9297d03dd7.diff

LOG: Revert rGa772f775a2ba401e95a0bbe73deb6300f1dc12c0 "[clang-tidy] Support C++14 in bugprone-signal-handler."

This was breaking a number of buildbots: https://lab.llvm.org/buildbot/#/builders/139/builds/26335

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
    clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
    clang-tools-extra/docs/ReleaseNotes.rst
    clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.rst
    clang-tools-extra/docs/clang-tidy/checks/list.rst
    clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/signal.h
    clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.c

Removed: 
    clang-tools-extra/docs/clang-tidy/checks/cert/msc54-cpp.rst
    clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/signal-handler/stdcpp.h
    clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.cpp


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
index fc91d79f26a65..132fbf85c1fe6 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
@@ -22,7 +22,6 @@ constexpr llvm::StringLiteral MinimalConformingFunctions[] = {
 // mentioned POSIX specification was not updated after 'quick_exit' appeared
 // in the C11 standard.
 // Also, we want to keep the "minimal set" a subset of the "POSIX set".
-// The list is repeated in bugprone-signal-handler.rst and should be kept up to date.
 constexpr llvm::StringLiteral POSIXConformingFunctions[] = {
     "_Exit",
     "_exit",
@@ -278,25 +277,6 @@ bool isStandardFunction(const FunctionDecl *FD) {
       FD->getCanonicalDecl()->getLocation());
 }
 
-/// Check if a statement is "C++-only".
-/// This includes all statements that have a class name with "CXX" prefix
-/// and every other statement that is declared in file ExprCXX.h.
-bool isCXXOnlyStmt(const Stmt *S) {
-  StringRef Name = S->getStmtClassName();
-  if (Name.startswith("CXX"))
-    return true;
-  // Check for all other class names in ExprCXX.h that have no 'CXX' prefix.
-  return isa<ArrayTypeTraitExpr, BuiltinBitCastExpr, CUDAKernelCallExpr,
-             CoawaitExpr, CoreturnStmt, CoroutineBodyStmt, CoroutineSuspendExpr,
-             CoyieldExpr, DependentCoawaitExpr, DependentScopeDeclRefExpr,
-             ExprWithCleanups, ExpressionTraitExpr, FunctionParmPackExpr,
-             LambdaExpr, MSDependentExistsStmt, MSPropertyRefExpr,
-             MSPropertySubscriptExpr, MaterializeTemporaryExpr, OverloadExpr,
-             PackExpansionExpr, SizeOfPackExpr, SubstNonTypeTemplateParmExpr,
-             SubstNonTypeTemplateParmPackExpr, TypeTraitExpr,
-             UserDefinedLiteral>(S);
-}
-
 /// Given a call graph node of a \p Caller function and a \p Callee that is
 /// called from \p Caller, get a \c CallExpr of the corresponding function call.
 /// It is unspecified which call is found if multiple calls exist, but the order
@@ -311,18 +291,6 @@ Expr *findCallExpr(const CallGraphNode *Caller, const CallGraphNode *Callee) {
   return FoundCallee->CallExpr;
 }
 
-SourceRange getSourceRangeOfStmt(const Stmt *S, ASTContext &Ctx) {
-  ParentMapContext &PM = Ctx.getParentMapContext();
-  DynTypedNode P = DynTypedNode::create(*S);
-  while (P.getSourceRange().isInvalid()) {
-    DynTypedNodeList PL = PM.getParents(P);
-    if (PL.size() != 1)
-      return {};
-    P = PL[0];
-  }
-  return P.getSourceRange();
-}
-
 } // namespace
 
 AST_MATCHER(FunctionDecl, isStandardFunction) {
@@ -349,7 +317,11 @@ void SignalHandlerCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
 
 bool SignalHandlerCheck::isLanguageVersionSupported(
     const LangOptions &LangOpts) const {
-  return !LangOpts.CPlusPlus17;
+  // FIXME: Make the checker useful on C++ code.
+  if (LangOpts.CPlusPlus)
+    return false;
+
+  return true;
 }
 
 void SignalHandlerCheck::registerMatchers(MatchFinder *Finder) {
@@ -360,23 +332,13 @@ void SignalHandlerCheck::registerMatchers(MatchFinder *Finder) {
                   unless(isExpandedFromMacro("SIG_IGN")),
                   unless(isExpandedFromMacro("SIG_DFL")))
           .bind("handler_expr");
-  auto HandlerLambda = cxxMemberCallExpr(
-      on(expr(ignoringParenImpCasts(lambdaExpr().bind("handler_lambda")))));
-  Finder->addMatcher(callExpr(callee(SignalFunction),
-                              hasArgument(1, anyOf(HandlerExpr, HandlerLambda)))
-                         .bind("register_call"),
-                     this);
+  Finder->addMatcher(
+      callExpr(callee(SignalFunction), hasArgument(1, HandlerExpr))
+          .bind("register_call"),
+      this);
 }
 
 void SignalHandlerCheck::check(const MatchFinder::MatchResult &Result) {
-  if (const auto *HandlerLambda =
-          Result.Nodes.getNodeAs<LambdaExpr>("handler_lambda")) {
-    diag(HandlerLambda->getBeginLoc(),
-         "lambda function is not allowed as signal handler (until C++17)")
-        << HandlerLambda->getSourceRange();
-    return;
-  }
-
   const auto *HandlerDecl =
       Result.Nodes.getNodeAs<FunctionDecl>("handler_decl");
   const auto *HandlerExpr = Result.Nodes.getNodeAs<DeclRefExpr>("handler_expr");
@@ -394,48 +356,32 @@ void SignalHandlerCheck::check(const MatchFinder::MatchResult &Result) {
   }
 
   if (!HandlerDecl->hasBody()) {
-    // Check the handler function.
-    // The warning is placed to the signal handler registration.
-    // No need to display a call chain and no need for more checks.
-    (void)checkFunction(HandlerDecl, HandlerExpr, {});
+    (void)checkFunction(HandlerDecl, HandlerExpr);
+    // Here checkFunction will put the messages to HandlerExpr.
+    // No need to show a call chain.
+    // Without code body there is nothing more to check.
     return;
   }
 
-  // FIXME: Update CallGraph::getNode to use canonical decl?
   CallGraphNode *HandlerNode = CG.getNode(HandlerDecl->getCanonicalDecl());
   assert(HandlerNode &&
          "Handler with body should be present in the call graph.");
   // Start from signal handler and visit every function call.
-  auto Itr = llvm::df_begin(HandlerNode), ItrE = llvm::df_end(HandlerNode);
-  while (Itr != ItrE) {
-    const auto *CallF = dyn_cast<FunctionDecl>((*Itr)->getDecl());
-    unsigned int PathL = Itr.getPathLength();
-    if (CallF) {
-      // A signal handler or a function transitively reachable from the signal
-      // handler was found to be unsafe.
-      // Generate notes for the whole call chain (including the signal handler
-      // registration).
-      const Expr *CallOrRef = (PathL > 1)
-                                  ? findCallExpr(Itr.getPath(PathL - 2), *Itr)
-                                  : HandlerExpr;
-      auto ChainReporter = [this, &Itr, HandlerExpr](bool SkipPathEnd) {
-        reportHandlerChain(Itr, HandlerExpr, SkipPathEnd);
-      };
-      // If problems were found in a function (`CallF`), skip the analysis of
-      // functions that are called from it.
-      if (checkFunction(CallF, CallOrRef, ChainReporter))
-        Itr.skipChildren();
-      else
-        ++Itr;
-    } else {
-      ++Itr;
+  for (auto Itr = llvm::df_begin(HandlerNode), ItrE = llvm::df_end(HandlerNode);
+       Itr != ItrE; ++Itr) {
+    if (const auto *CallF = dyn_cast<FunctionDecl>((*Itr)->getDecl())) {
+      unsigned int PathL = Itr.getPathLength();
+      const Expr *CallOrRef = (PathL == 1)
+                                  ? HandlerExpr
+                                  : findCallExpr(Itr.getPath(PathL - 2), *Itr);
+      if (checkFunction(CallF, CallOrRef))
+        reportHandlerChain(Itr, HandlerExpr);
     }
   }
 }
 
-bool SignalHandlerCheck::checkFunction(
-    const FunctionDecl *FD, const Expr *CallOrRef,
-    std::function<void(bool)> ChainReporter) {
+bool SignalHandlerCheck::checkFunction(const FunctionDecl *FD,
+                                       const Expr *CallOrRef) {
   bool FunctionIsCalled = isa<CallExpr>(CallOrRef);
 
   if (isStandardFunction(FD)) {
@@ -444,9 +390,7 @@ bool SignalHandlerCheck::checkFunction(
                                      "asynchronous-safe; "
                                      "%select{using it as|calling it from}1 "
                                      "a signal handler may be dangerous")
-          << FD << FunctionIsCalled << CallOrRef->getSourceRange();
-      if (ChainReporter)
-        ChainReporter(/*SkipPathEnd=*/true);
+          << FD << FunctionIsCalled;
       return true;
     }
     return false;
@@ -457,74 +401,23 @@ bool SignalHandlerCheck::checkFunction(
                                    "asynchronous-safe; "
                                    "%select{using it as|calling it from}1 "
                                    "a signal handler may be dangerous")
-        << FD << FunctionIsCalled << CallOrRef->getSourceRange();
-    if (ChainReporter)
-      ChainReporter(/*SkipPathEnd=*/true);
+        << FD << FunctionIsCalled;
     return true;
   }
 
-  if (getLangOpts().CPlusPlus)
-    return checkFunctionCPP14(FD, CallOrRef, ChainReporter);
-
   return false;
 }
 
-bool SignalHandlerCheck::checkFunctionCPP14(
-    const FunctionDecl *FD, const Expr *CallOrRef,
-    std::function<void(bool)> ChainReporter) {
-  if (!FD->isExternC()) {
-    diag(CallOrRef->getBeginLoc(),
-         "functions without C linkage are not allowed as signal "
-         "handler (until C++17)");
-    if (ChainReporter)
-      ChainReporter(/*SkipPathEnd=*/true);
-    return true;
-  }
-
-  const FunctionDecl *FBody;
-  const Stmt *BodyS = FD->getBody(FBody);
-  if (!BodyS)
-    return false;
-
-  bool StmtProblemsFound = false;
-  ASTContext &Ctx = FBody->getASTContext();
-  auto Matches =
-      match(decl(forEachDescendant(stmt().bind("stmt"))), *FBody, Ctx);
-  for (const auto &Match : Matches) {
-    const auto *FoundS = Match.getNodeAs<Stmt>("stmt");
-    if (isCXXOnlyStmt(FoundS)) {
-      SourceRange R = getSourceRangeOfStmt(FoundS, Ctx);
-      if (R.isInvalid())
-        continue;
-      diag(R.getBegin(),
-           "C++-only construct is not allowed in signal handler (until C++17)")
-          << R;
-      diag(R.getBegin(), "internally, the statement is parsed as a '%0'",
-           DiagnosticIDs::Remark)
-          << FoundS->getStmtClassName();
-      if (ChainReporter)
-        ChainReporter(/*SkipPathEnd=*/false);
-      StmtProblemsFound = true;
-    }
-  }
-
-  return StmtProblemsFound;
-}
-
 bool SignalHandlerCheck::isStandardFunctionAsyncSafe(
     const FunctionDecl *FD) const {
   assert(isStandardFunction(FD));
 
   const IdentifierInfo *II = FD->getIdentifier();
   // Unnamed functions are not explicitly allowed.
-  // C++ std operators may be unsafe and not within the
-  // "common subset of C and C++".
   if (!II)
     return false;
 
-  if (!FD->isInStdNamespace() && !FD->isGlobal())
-    return false;
-
+  // FIXME: Improve for C++ (check for namespace).
   if (ConformingFunctions.count(II->getName()))
     return true;
 
@@ -533,7 +426,7 @@ bool SignalHandlerCheck::isStandardFunctionAsyncSafe(
 
 void SignalHandlerCheck::reportHandlerChain(
     const llvm::df_iterator<clang::CallGraphNode *> &Itr,
-    const DeclRefExpr *HandlerRef, bool SkipPathEnd) {
+    const DeclRefExpr *HandlerRef) {
   int CallLevel = Itr.getPathLength() - 2;
   assert(CallLevel >= -1 && "Empty iterator?");
 
@@ -542,21 +435,16 @@ void SignalHandlerCheck::reportHandlerChain(
     Callee = Caller;
     Caller = Itr.getPath(CallLevel);
     const Expr *CE = findCallExpr(Caller, Callee);
-    if (SkipPathEnd)
-      SkipPathEnd = false;
-    else
-      diag(CE->getBeginLoc(), "function %0 called here from %1",
-           DiagnosticIDs::Note)
-          << cast<FunctionDecl>(Callee->getDecl())
-          << cast<FunctionDecl>(Caller->getDecl());
+    diag(CE->getBeginLoc(), "function %0 called here from %1",
+         DiagnosticIDs::Note)
+        << cast<FunctionDecl>(Callee->getDecl())
+        << cast<FunctionDecl>(Caller->getDecl());
     --CallLevel;
   }
 
-  if (!SkipPathEnd)
-    diag(HandlerRef->getBeginLoc(),
-         "function %0 registered here as signal handler", DiagnosticIDs::Note)
-        << cast<FunctionDecl>(Caller->getDecl())
-        << HandlerRef->getSourceRange();
+  diag(HandlerRef->getBeginLoc(),
+       "function %0 registered here as signal handler", DiagnosticIDs::Note)
+      << cast<FunctionDecl>(Caller->getDecl()) << HandlerRef->getSourceRange();
 }
 
 } // namespace bugprone

diff  --git a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
index 01090b42d62ad..01b63614163c1 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
+++ b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
@@ -37,24 +37,13 @@ class SignalHandlerCheck : public ClangTidyCheck {
   /// Should test the properties of the function, and check in the code body.
   /// Should not check function calls in the code (this part is done by the call
   /// graph scan).
-  /// Bug reports are generated for the whole code body (no stop at the first
-  /// found issue). For issues that are not in the code body, only one
-  /// bug report is generated.
-  /// \param FD The function to check. It may or may not have a definition.
-  /// \param CallOrRef Location of the call to this function (in another
+  /// @param FD The function to check. It may or may not have a definition.
+  /// @param CallOrRef Location of the call to this function (in another
   /// function) or the reference to the function (if it is used as a registered
   /// signal handler). This is the location where diagnostics are to be placed.
-  /// \param ChainReporter A function that adds bug report notes to display the
-  /// chain of called functions from signal handler registration to the current
-  /// function. This is called at every generated bug report.
-  /// The bool parameter is used like \c SkipPathEnd in \c reportHandlerChain .
-  /// \return Returns true if a diagnostic was emitted for this function.
-  bool checkFunction(const FunctionDecl *FD, const Expr *CallOrRef,
-                     std::function<void(bool)> ChainReporter);
-  /// Similar as \c checkFunction but only check for C++14 rules.
-  bool checkFunctionCPP14(const FunctionDecl *FD, const Expr *CallOrRef,
-                          std::function<void(bool)> ChainReporter);
-  /// Returns true if a standard library function is considered
+  /// @return Returns true if a diagnostic was emitted for this function.
+  bool checkFunction(const FunctionDecl *FD, const Expr *CallOrRef);
+  /// Returns true if a standard library function is considered as
   /// asynchronous-safe.
   bool isStandardFunctionAsyncSafe(const FunctionDecl *FD) const;
   /// Add diagnostic notes to show the call chain of functions from a signal
@@ -65,10 +54,8 @@ class SignalHandlerCheck : public ClangTidyCheck {
   /// function call.
   /// @param HandlerRef Reference to the signal handler function where it is
   /// registered as signal handler.
-  /// @param SkipPathEnd If true the last item of the call chain (farthest away
-  /// from the \c signal call) is omitted from note generation.
   void reportHandlerChain(const llvm::df_iterator<clang::CallGraphNode *> &Itr,
-                          const DeclRefExpr *HandlerRef, bool SkipPathEnd);
+                          const DeclRefExpr *HandlerRef);
 
   clang::CallGraph CG;
 

diff  --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
index 5686d3edafb06..3aada6f37f37d 100644
--- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
@@ -265,8 +265,6 @@ class CERTModule : public ClangTidyModule {
     CheckFactories.registerCheck<LimitedRandomnessCheck>("cert-msc50-cpp");
     CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>(
         "cert-msc51-cpp");
-    CheckFactories.registerCheck<bugprone::SignalHandlerCheck>(
-        "cert-msc54-cpp");
     // OOP
     CheckFactories.registerCheck<performance::MoveConstructorInitCheck>(
         "cert-oop11-cpp");

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 8a6fe30981813..840e3aac32578 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -102,20 +102,9 @@ New checks
 New check aliases
 ^^^^^^^^^^^^^^^^^
 
-- New alias :doc:`cert-msc54-cpp
-  <clang-tidy/checks/cert/msc54-cpp>` to
-  :doc:`bugprone-signal-handler
-  <clang-tidy/checks/bugprone/signal-handler>` was added.
-
-
 Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- Improved :doc:`bugprone-signal-handler
-  <clang-tidy/checks/bugprone/signal-handler>` check. Partial
-  support for C++14 signal handler rules was added. Bug report generation was
-  improved.
-
 Removed checks
 ^^^^^^^^^^^^^^
 

diff  --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.rst
index 8a11924c465dd..288bace9c737a 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.rst
@@ -3,95 +3,34 @@
 bugprone-signal-handler
 =======================
 
-Finds specific constructs in signal handler functions that can cause undefined
-behavior. The rules for what is allowed 
diff er between C++ language versions.
-
-Checked signal handler rules for C:
-
-- Calls to non-asynchronous-safe functions are not allowed.
-
-Checked signal handler rules for up to and including C++14:
-
-- Calls to non-asynchronous-safe functions are not allowed.
-- C++-specific code constructs are not allowed in signal handlers.
-  In other words, only the common subset of C and C++ is allowed to be used.
-- Calls to functions with non-C linkage are not allowed (including the signal
-  handler itself).
-
-The check is disabled on C++17 and later.
-
-Asnychronous-safety is determined by comparing the function's name against a set
-of known functions. In addition, the function must come from a system header
-include and in a global namespace. The (possible) arguments passed to the
-function are not checked. Any function that cannot be determined to be
-asynchronous-safe is assumed to be non-asynchronous-safe by the check,
+Finds functions registered as signal handlers that call non asynchronous-safe
+functions. Any function that cannot be determined to be an asynchronous-safe
+function call is assumed to be non-asynchronous-safe by the checker,
 including user functions for which only the declaration is visible.
-Calls to user-defined functions with visible definitions are checked
-recursively.
+User function calls with visible definition are checked recursively.
+The check handles only C code. Only the function names are considered and the
+fact that the function is a system-call, but no other restrictions on the
+arguments passed to the functions (the ``signal`` call is allowed without
+restrictions).
 
-This check implements the CERT C Coding Standard rule
+This check corresponds to the CERT C Coding Standard rule
 `SIG30-C. Call only asynchronous-safe functions within signal handlers
 <https://www.securecoding.cert.org/confluence/display/c/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers>`_
-and the rule
-`MSC54-CPP. A signal handler must be a plain old function
-<https://wiki.sei.cmu.edu/confluence/display/cplusplus/MSC54-CPP.+A+signal+handler+must+be+a+plain+old+function>`_.
-It has the alias names ``cert-sig30-c`` and ``cert-msc54-cpp``.
-
-Options
--------
+and has an alias name ``cert-sig30-c``.
 
 .. option:: AsyncSafeFunctionSet
 
   Selects which set of functions is considered as asynchronous-safe
-  (and therefore allowed in signal handlers). It can be set to the following values:
-  
-  ``minimal``
-     Selects a minimal set that is defined in the CERT SIG30-C rule.
-     and includes functions ``abort()``, ``_Exit()``, ``quick_exit()`` and
-     ``signal()``.
-  ``POSIX``
-     Selects a larger set of functions that is listed in POSIX.1-2017 (see `this
-     link
-     <https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03>`_
-     for more information). The following functions are included:
-     ``_Exit``, ``_exit``, ``abort``, ``accept``, ``access``, ``aio_error``,
-     ``aio_return``, ``aio_suspend``, ``alarm``, ``bind``, ``cfgetispeed``,
-     ``cfgetospeed``, ``cfsetispeed``, ``cfsetospeed``, ``chdir``, ``chmod``,
-     ``chown``, ``clock_gettime``, ``close``, ``connect``, ``creat``, ``dup``,
-     ``dup2``, ``execl``, ``execle``, ``execv``, ``execve``, ``faccessat``,
-     ``fchdir``, ``fchmod``, ``fchmodat``, ``fchown``, ``fchownat``, ``fcntl``,
-     ``fdatasync``, ``fexecve``, ``ffs``, ``fork``, ``fstat``, ``fstatat``,
-     ``fsync``, ``ftruncate``, ``futimens``, ``getegid``, ``geteuid``,
-     ``getgid``, ``getgroups``, ``getpeername``, ``getpgrp``, ``getpid``,
-     ``getppid``, ``getsockname``, ``getsockopt``, ``getuid``, ``htonl``,
-     ``htons``, ``kill``, ``link``, ``linkat``, ``listen``, ``longjmp``,
-     ``lseek``, ``lstat``, ``memccpy``, ``memchr``, ``memcmp``, ``memcpy``,
-     ``memmove``, ``memset``, ``mkdir``, ``mkdirat``, ``mkfifo``, ``mkfifoat``,
-     ``mknod``, ``mknodat``, ``ntohl``, ``ntohs``, ``open``, ``openat``,
-     ``pause``, ``pipe``, ``poll``, ``posix_trace_event``, ``pselect``,
-     ``pthread_kill``, ``pthread_self``, ``pthread_sigmask``, ``quick_exit``,
-     ``raise``, ``read``, ``readlink``, ``readlinkat``, ``recv``, ``recvfrom``,
-     ``recvmsg``, ``rename``, ``renameat``, ``rmdir``, ``select``, ``sem_post``,
-     ``send``, ``sendmsg``, ``sendto``, ``setgid``, ``setpgid``, ``setsid``,
-     ``setsockopt``, ``setuid``, ``shutdown``, ``sigaction``, ``sigaddset``,
-     ``sigdelset``, ``sigemptyset``, ``sigfillset``, ``sigismember``,
-     ``siglongjmp``, ``signal``, ``sigpause``, ``sigpending``, ``sigprocmask``,
-     ``sigqueue``, ``sigset``, ``sigsuspend``, ``sleep``, ``sockatmark``,
-     ``socket``, ``socketpair``, ``stat``, ``stpcpy``, ``stpncpy``,
-     ``strcat``, ``strchr``, ``strcmp``, ``strcpy``, ``strcspn``, ``strlen``,
-     ``strncat``, ``strncmp``, ``strncpy``, ``strnlen``, ``strpbrk``,
-     ``strrchr``, ``strspn``, ``strstr``, ``strtok_r``, ``symlink``,
-     ``symlinkat``, ``tcdrain``, ``tcflow``, ``tcflush``, ``tcgetattr``,
-     ``tcgetpgrp``, ``tcsendbreak``, ``tcsetattr``, ``tcsetpgrp``,
-     ``time``, ``timer_getoverrun``, ``timer_gettime``, ``timer_settime``,
-     ``times``, ``umask``, ``uname``, ``unlink``, ``unlinkat``, ``utime``,
-     ``utimensat``, ``utimes``, ``wait``, ``waitpid``, ``wcpcpy``,
-     ``wcpncpy``, ``wcscat``, ``wcschr``, ``wcscmp``, ``wcscpy``, ``wcscspn``,
-     ``wcslen``, ``wcsncat``, ``wcsncmp``, ``wcsncpy``, ``wcsnlen``, ``wcspbrk``,
-     ``wcsrchr``, ``wcsspn``, ``wcsstr``, ``wcstok``, ``wmemchr``, ``wmemcmp``,
-     ``wmemcpy``, ``wmemmove``, ``wmemset``, ``write``
-
-     The function ``quick_exit`` is not included in the POSIX list but it
-     is included here in the set of safe functions.
-
-  The default value is ``POSIX``.
+  (and therefore allowed in signal handlers). Value ``minimal`` selects
+  a minimal set that is defined in the CERT SIG30-C rule and includes functions
+  ``abort()``, ``_Exit()``, ``quick_exit()`` and ``signal()``. Value ``POSIX``
+  selects a larger set of functions that is listed in POSIX.1-2017 (see `this
+  link
+  <https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03>`_
+  for more information).
+  The function ``quick_exit`` is not included in the shown list. It is
+  assumable that  the reason is that the list was not updated for C11.
+  The checker includes ``quick_exit`` in the set of safe functions.
+  Functions registered as exit handlers are not checked.
+
+  Default is ``POSIX``.

diff  --git a/clang-tools-extra/docs/clang-tidy/checks/cert/msc54-cpp.rst b/clang-tools-extra/docs/clang-tidy/checks/cert/msc54-cpp.rst
deleted file mode 100644
index 2c966cb2b5f01..0000000000000
--- a/clang-tools-extra/docs/clang-tidy/checks/cert/msc54-cpp.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-.. title:: clang-tidy - cert-msc54-cpp
-.. meta::
-   :http-equiv=refresh: 5;URL=../bugprone/signal-handler.html
-
-cert-msc54-cpp
-==============
-
-The cert-msc54-cpp check is an alias, please see
-`bugprone-signal-handler <../bugprone/signal-handler.html>`_
-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 4862f584c3263..a7c6247ab96bf 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -383,7 +383,6 @@ Clang-Tidy Checks
    `cert-flp37-c <cert/flp37-c.html>`_, `bugprone-suspicious-memory-comparison <bugprone/suspicious-memory-comparison.html>`_,
    `cert-msc30-c <cert/msc30-c.html>`_, `cert-msc50-cpp <cert/msc50-cpp.html>`_,
    `cert-msc32-c <cert/msc32-c.html>`_, `cert-msc51-cpp <cert/msc51-cpp.html>`_,
-   `cert-msc54-cpp <cert/msc54-cpp.html>`_, `bugprone-signal-handler <bugprone/signal-handler.html>`_,
    `cert-oop11-cpp <cert/oop11-cpp.html>`_, `performance-move-constructor-init <performance/move-constructor-init.html>`_,
    `cert-oop54-cpp <cert/oop54-cpp.html>`_, `bugprone-unhandled-self-assignment <bugprone/unhandled-self-assignment.html>`_,
    `cert-pos44-c <cert/pos44-c.html>`_, `bugprone-bad-signal-to-kill-thread <bugprone/bad-signal-to-kill-thread.html>`_,

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/signal.h b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/signal.h
index b943d07fbc8eb..3326a610d3d90 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/signal.h
+++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/signal.h
@@ -13,12 +13,10 @@ typedef void (*sighandler_t)(int);
 
 void _sig_ign(int);
 void _sig_dfl(int);
-void _sig_err(int);
 
 #define SIGINT 1
 #define SIG_IGN _sig_ign
 #define SIG_DFL _sig_dfl
-#define SIG_ERR _sig_err
 
 sighandler_t signal(int, sighandler_t);
 

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/signal-handler/stdcpp.h b/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/signal-handler/stdcpp.h
deleted file mode 100644
index 72a9ba152fbdb..0000000000000
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/signal-handler/stdcpp.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===--- Header for test bugprone-signal-handler.cpp ------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#define SIGINT 1
-#define SIG_IGN std::_sig_ign
-#define SIG_DFL std::_sig_dfl
-
-namespace std {
-
-void _sig_ign(int);
-void _sig_dfl(int);
-
-typedef void (*sighandler_t)(int);
-sighandler_t signal(int, sighandler_t);
-
-void abort();
-void _Exit(int);
-void quick_exit(int);
-
-void other_call();
-
-struct SysStruct {
-  void operator<<(int);
-};
-
-} // namespace std
-
-namespace system_other {
-
-typedef void (*sighandler_t)(int);
-sighandler_t signal(int, sighandler_t);
-
-} // namespace system_other

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.c
index 791c244dcbe18..51f7b07a39109 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.c
@@ -18,6 +18,7 @@ void f_extern(void);
 void handler_printf(int) {
   printf("1234");
   // CHECK-NOTES: :[[@LINE-1]]:3: warning: standard function 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-NOTES: :[[@LINE-2]]:3: note: function 'printf' called here from 'handler_printf'
   // CHECK-NOTES: :[[@LINE+4]]:18: note: function 'handler_printf' registered here as signal handler
 }
 
@@ -28,6 +29,7 @@ void test_printf(void) {
 void handler_extern(int) {
   f_extern();
   // CHECK-NOTES: :[[@LINE-1]]:3: warning: cannot verify that external function 'f_extern' is asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-NOTES: :[[@LINE-2]]:3: note: function 'f_extern' called here from 'handler_extern'
   // CHECK-NOTES: :[[@LINE+4]]:18: note: function 'handler_extern' registered here as signal handler
 }
 
@@ -50,6 +52,7 @@ void test_ok(void) {
 void f_bad(void) {
   printf("1234");
   // CHECK-NOTES: :[[@LINE-1]]:3: warning: standard function 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-NOTES: :[[@LINE-2]]:3: note: function 'printf' called here from 'f_bad'
   // CHECK-NOTES: :[[@LINE+5]]:3: note: function 'f_bad' called here from 'handler_bad'
   // CHECK-NOTES: :[[@LINE+8]]:18: note: function 'handler_bad' registered here as signal handler
 }
@@ -65,6 +68,7 @@ void test_bad(void) {
 void f_bad1(void) {
   printf("1234");
   // CHECK-NOTES: :[[@LINE-1]]:3: warning: standard function 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-NOTES: :[[@LINE-2]]:3: note: function 'printf' called here from 'f_bad1'
   // CHECK-NOTES: :[[@LINE+6]]:3: note: function 'f_bad1' called here from 'f_bad2'
   // CHECK-NOTES: :[[@LINE+9]]:3: note: function 'f_bad2' called here from 'handler_bad1'
   // CHECK-NOTES: :[[@LINE+13]]:18: note: function 'handler_bad1' registered here as signal handler
@@ -96,6 +100,7 @@ void handler_false_condition(int) {
   if (0)
     printf("1234");
   // CHECK-NOTES: :[[@LINE-1]]:5: warning: standard function 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-NOTES: :[[@LINE-2]]:5: note: function 'printf' called here from 'handler_false_condition'
   // CHECK-NOTES: :[[@LINE+4]]:18: note: function 'handler_false_condition' registered here as signal handler
 }
 
@@ -106,9 +111,11 @@ void test_false_condition(void) {
 void handler_multiple_calls(int) {
   f_extern();
   // CHECK-NOTES: :[[@LINE-1]]:3: warning: cannot verify that external function 'f_extern' is asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
-  // CHECK-NOTES: :[[@LINE+9]]:18: note: function 'handler_multiple_calls' registered here as signal handler
+  // CHECK-NOTES: :[[@LINE-2]]:3: note: function 'f_extern' called here from 'handler_multiple_calls'
+  // CHECK-NOTES: :[[@LINE+10]]:18: note: function 'handler_multiple_calls' registered here as signal handler
   printf("1234");
   // CHECK-NOTES: :[[@LINE-1]]:3: warning: standard function 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-NOTES: :[[@LINE-2]]:3: note: function 'printf' called here from 'handler_multiple_calls'
   // CHECK-NOTES: :[[@LINE+6]]:18: note: function 'handler_multiple_calls' registered here as signal handler
   f_extern();
   // first 'f_extern' call found only
@@ -129,11 +136,13 @@ void handler_recursive(int) {
 void f_recursive(void) {
   f_extern();
   // CHECK-NOTES: :[[@LINE-1]]:3: warning: cannot verify that external function 'f_extern' is asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
-  // CHECK-NOTES: :[[@LINE-8]]:3: note: function 'f_recursive' called here from 'handler_recursive'
-  // CHECK-NOTES: :[[@LINE+9]]:18: note: function 'handler_recursive' registered here as signal handler
+  // CHECK-NOTES: :[[@LINE-2]]:3: note: function 'f_extern' called here from 'f_recursive'
+  // CHECK-NOTES: :[[@LINE-9]]:3: note: function 'f_recursive' called here from 'handler_recursive'
+  // CHECK-NOTES: :[[@LINE+10]]:18: note: function 'handler_recursive' registered here as signal handler
   printf("");
   // CHECK-NOTES: :[[@LINE-1]]:3: warning: standard function 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
-  // CHECK-NOTES: :[[@LINE-12]]:3: note: function 'f_recursive' called here from 'handler_recursive'
+  // CHECK-NOTES: :[[@LINE-2]]:3: note: function 'printf' called here from 'f_recursive'
+  // CHECK-NOTES: :[[@LINE-14]]:3: note: function 'f_recursive' called here from 'handler_recursive'
   // CHECK-NOTES: :[[@LINE+5]]:18: note: function 'handler_recursive' registered here as signal handler
   handler_recursive(2);
 }
@@ -145,6 +154,7 @@ void test_recursive(void) {
 void f_multiple_paths(void) {
   printf("");
   // CHECK-NOTES: :[[@LINE-1]]:3: warning: standard function 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-NOTES: :[[@LINE-2]]:3: note: function 'printf' called here from 'f_multiple_paths'
   // CHECK-NOTES: :[[@LINE+5]]:3: note: function 'f_multiple_paths' called here from 'handler_multiple_paths'
   // CHECK-NOTES: :[[@LINE+9]]:18: note: function 'handler_multiple_paths' registered here as signal handler
 }

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.cpp
deleted file mode 100644
index 0d6761e2805b6..0000000000000
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/signal-handler.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-// RUN: %check_clang_tidy -std=c++14 %s bugprone-signal-handler %t -- -- -isystem %clang_tidy_headers -isystem %S/Inputs/signal-handler
-
-#include "stdcpp.h"
-#include "stdio.h"
-
-// Functions called "signal" that are 
diff erent from the system version.
-typedef void (*callback_t)(int);
-void signal(int, callback_t, int);
-namespace ns {
-void signal(int, callback_t);
-}
-
-extern "C" void handler_unsafe(int) {
-  printf("xxx");
-}
-
-extern "C" void handler_unsafe_1(int) {
-  printf("xxx");
-}
-
-namespace test_invalid_handler {
-
-void handler_non_extern_c(int) {
-  printf("xxx");
-}
-
-struct A {
-  static void handler_member(int) {
-    printf("xxx");
-  }
-};
-
-void test() {
-  std::signal(SIGINT, handler_unsafe_1);
-  // CHECK-MESSAGES: :[[@LINE-17]]:3: warning: standard function 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:23: note: function 'handler_unsafe_1' registered here as signal handler
-
-  std::signal(SIGINT, handler_non_extern_c);
-  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: functions without C linkage are not allowed as signal handler (until C++17) [bugprone-signal-handler]
-  std::signal(SIGINT, A::handler_member);
-  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: functions without C linkage are not allowed as signal handler (until C++17) [bugprone-signal-handler]
-  std::signal(SIGINT, [](int) { printf("xxx"); });
-  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: lambda function is not allowed as signal handler (until C++17) [bugprone-signal-handler]
-
-  // This case is (deliberately) not found by the checker.
-  std::signal(SIGINT, [](int) -> callback_t { return &handler_unsafe; }(1));
-}
-
-} // namespace test_invalid_handler
-
-namespace test_non_standard_signal_call {
-
-struct Signal {
-  static void signal(int, callback_t);
-};
-
-void test() {
-  // No diagnostics here. All these signal calls 
diff er from the standard system one.
-  signal(SIGINT, handler_unsafe, 1);
-  ns::signal(SIGINT, handler_unsafe);
-  Signal::signal(SIGINT, handler_unsafe);
-  system_other::signal(SIGINT, handler_unsafe);
-}
-
-} // namespace test_non_standard_signal_call
-
-namespace test_cpp_construct_in_handler {
-
-struct Struct {
-  virtual ~Struct() {}
-  void f1();
-  int *begin();
-  int *end();
-  static void f2();
-};
-struct Derived : public Struct {
-};
-
-struct X {
-  X(int, float);
-};
-
-Struct *S_Global;
-const Struct *S_GlobalConst;
-
-void f_non_extern_c() {
-}
-
-void f_default_arg(int P1 = 0) {
-}
-
-extern "C" void handler_cpp(int) {
-  using namespace ::test_cpp_construct_in_handler;
-
-  // These calls are not found as problems.
-  // (Called functions are not analyzed if the current function has already
-  // other problems.)
-  f_non_extern_c();
-  Struct::f2();
-  // 'auto' is not disallowed
-  auto Auto = 28u;
-
-  Struct S;
-  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:10: remark: internally, the statement is parsed as a 'CXXConstructExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  S_Global->f1();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXMemberCallExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  const Struct &SRef = Struct();
-  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:24: remark: internally, the statement is parsed as a 'CXXBindTemporaryExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  X(3, 4.4);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXTemporaryObjectExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-
-  auto L = [](int i) { printf("%d", i); };
-  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:12: remark: internally, the statement is parsed as a 'CXXConstructExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  L(2);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXOperatorCallExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-
-  try {
-    // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-    // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXTryStmt'
-    // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-    int A;
-  } catch (int) {
-  };
-  // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-3]]:5: remark: internally, the statement is parsed as a 'CXXCatchStmt'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-
-  throw(12);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXThrowExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-
-  for (int I : S) {
-  }
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-3]]:3: remark: internally, the statement is parsed as a 'CXXForRangeStmt'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  // CHECK-MESSAGES: :[[@LINE-5]]:14: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-6]]:14: remark: internally, the statement is parsed as a 'CXXMemberCallExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-
-  int Int = *(reinterpret_cast<int *>(&S));
-  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:15: remark: internally, the statement is parsed as a 'CXXReinterpretCastExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  Int = static_cast<int>(12.34);
-  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:9: remark: internally, the statement is parsed as a 'CXXStaticCastExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  Derived *Der = dynamic_cast<Derived *>(S_Global);
-  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:18: remark: internally, the statement is parsed as a 'CXXDynamicCastExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  Struct *SPtr = const_cast<Struct *>(S_GlobalConst);
-  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:18: remark: internally, the statement is parsed as a 'CXXConstCastExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  Int = int(12.34);
-  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:9: remark: internally, the statement is parsed as a 'CXXFunctionalCastExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-
-  int *IPtr = new int[10];
-  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:15: remark: internally, the statement is parsed as a 'CXXNewExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  delete[] IPtr;
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXDeleteExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  IPtr = nullptr;
-  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:10: remark: internally, the statement is parsed as a 'CXXNullPtrLiteralExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  bool Bool = true;
-  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:15: remark: internally, the statement is parsed as a 'CXXBoolLiteralExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-  f_default_arg();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXDefaultArgExpr'
-  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler
-}
-
-void test() {
-  std::signal(SIGINT, handler_cpp);
-}
-
-} // namespace test_cpp_construct_in_handler
-
-namespace test_cpp_indirect {
-
-void non_extern_c() {
-  int *P = nullptr;
-}
-
-extern "C" void call_cpp_indirect() {
-  int *P = nullptr;
-  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE-2]]:12: remark: internally, the statement is parsed as a 'CXXNullPtrLiteralExpr'
-  // CHECK-MESSAGES: :[[@LINE+8]]:3: note: function 'call_cpp_indirect' called here from 'handler_cpp_indirect'
-  // CHECK-MESSAGES: :[[@LINE+11]]:23: note: function 'handler_cpp_indirect' registered here as signal handler
-}
-
-extern "C" void handler_cpp_indirect(int) {
-  non_extern_c();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: functions without C linkage are not allowed as signal handler (until C++17) [bugprone-signal-handler]
-  // CHECK-MESSAGES: :[[@LINE+5]]:23: note: function 'handler_cpp_indirect' registered here as signal handler
-  call_cpp_indirect();
-}
-
-void test() {
-  std::signal(SIGINT, handler_cpp_indirect);
-}
-
-} // namespace test_cpp_indirect


        


More information about the cfe-commits mailing list