[clang-tools-extra] cc7ed0c - [clang-tidy] bugprone-signal-handler: Message improvement and code refactoring.

Balázs Kéri via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 7 00:39:55 PDT 2022


Author: Balázs Kéri
Date: 2022-04-07T09:38:58+02:00
New Revision: cc7ed0caaca58bb38c789dcf2e0aade5f68f1e02

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

LOG: [clang-tidy] bugprone-signal-handler: Message improvement and code refactoring.

Another change of the code design.
Code simplified again, now there is a single place to check
a handler function and less functions for bug report emitting.
More details are added to the bug report messages.

Reviewed By: whisperity

Differential Revision: https://reviews.llvm.org/D118370

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
    clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler-minimal.c
    clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler-posix.c
    clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler.c

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
index 983a7c0610d71..37d373905b693 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
@@ -11,215 +11,9 @@
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/ADT/STLExtras.h"
 
-using namespace clang::ast_matchers;
-
-namespace clang {
-namespace tidy {
-
-template <>
-struct OptionEnumMapping<
-    bugprone::SignalHandlerCheck::AsyncSafeFunctionSetType> {
-  static llvm::ArrayRef<std::pair<
-      bugprone::SignalHandlerCheck::AsyncSafeFunctionSetType, StringRef>>
-  getEnumMapping() {
-    static constexpr std::pair<
-        bugprone::SignalHandlerCheck::AsyncSafeFunctionSetType, StringRef>
-        Mapping[] = {
-            {bugprone::SignalHandlerCheck::AsyncSafeFunctionSetType::Minimal,
-             "minimal"},
-            {bugprone::SignalHandlerCheck::AsyncSafeFunctionSetType::POSIX,
-             "POSIX"},
-        };
-    return makeArrayRef(Mapping);
-  }
-};
-
-namespace bugprone {
-
-namespace {
-
-bool isSystemCall(const FunctionDecl *FD) {
-  // Find a possible redeclaration in system header.
-  // FIXME: Looking at the canonical declaration is not the most exact way
-  // to do this.
-
-  // Most common case will be inclusion directly from a header.
-  // This works fine by using canonical declaration.
-  // a.c
-  // #include <sysheader.h>
-
-  // Next most common case will be extern declaration.
-  // Can't catch this with either approach.
-  // b.c
-  // extern void sysfunc(void);
-
-  // Canonical declaration is the first found declaration, so this works.
-  // c.c
-  // #include <sysheader.h>
-  // extern void sysfunc(void); // redecl won't matter
-
-  // This does not work with canonical declaration.
-  // Probably this is not a frequently used case but may happen (the first
-  // declaration can be in a non-system header for example).
-  // d.c
-  // extern void sysfunc(void); // Canonical declaration, not in system header.
-  // #include <sysheader.h>
-
-  return FD->getASTContext().getSourceManager().isInSystemHeader(
-      FD->getCanonicalDecl()->getLocation());
-}
-
-/// Given a call graph node of a function and another one that is called from
-/// this function, get a CallExpr of the corresponding function call.
-/// It is unspecified which call is found if multiple calls exist, but the order
-/// should be deterministic (depend only on the AST).
-Expr *findCallExpr(const CallGraphNode *Caller, const CallGraphNode *Callee) {
-  auto FoundCallee = llvm::find_if(
-      Caller->callees(), [Callee](const CallGraphNode::CallRecord &Call) {
-        return Call.Callee == Callee;
-      });
-  assert(FoundCallee != Caller->end() &&
-         "Callee should be called from the caller function here.");
-  return FoundCallee->CallExpr;
-}
-
-} // namespace
-
-AST_MATCHER(FunctionDecl, isSystemCall) { return isSystemCall(&Node); }
-
-SignalHandlerCheck::SignalHandlerCheck(StringRef Name,
-                                       ClangTidyContext *Context)
-    : ClangTidyCheck(Name, Context),
-      AsyncSafeFunctionSet(
-          Options.get("AsyncSafeFunctionSet", AsyncSafeFunctionSetType::POSIX)),
-      ConformingFunctions(AsyncSafeFunctionSet ==
-                                  AsyncSafeFunctionSetType::Minimal
-                              ? MinimalConformingFunctions
-                              : POSIXConformingFunctions) {}
-
-void SignalHandlerCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
-  Options.store(Opts, "AsyncSafeFunctionSet", AsyncSafeFunctionSet);
-}
-
-bool SignalHandlerCheck::isLanguageVersionSupported(
-    const LangOptions &LangOpts) const {
-  // FIXME: Make the checker useful on C++ code.
-  if (LangOpts.CPlusPlus)
-    return false;
-
-  return true;
-}
-
-void SignalHandlerCheck::registerMatchers(MatchFinder *Finder) {
-  auto SignalFunction = functionDecl(hasAnyName("::signal", "::std::signal"),
-                                     parameterCountIs(2), isSystemCall());
-  auto HandlerExpr =
-      declRefExpr(hasDeclaration(functionDecl().bind("handler_decl")),
-                  unless(isExpandedFromMacro("SIG_IGN")),
-                  unless(isExpandedFromMacro("SIG_DFL")))
-          .bind("handler_expr");
-  Finder->addMatcher(
-      callExpr(callee(SignalFunction), hasArgument(1, HandlerExpr))
-          .bind("register_call"),
-      this);
-}
-
-void SignalHandlerCheck::check(const MatchFinder::MatchResult &Result) {
-  const auto *SignalCall = Result.Nodes.getNodeAs<CallExpr>("register_call");
-  const auto *HandlerDecl =
-      Result.Nodes.getNodeAs<FunctionDecl>("handler_decl");
-  const auto *HandlerExpr = Result.Nodes.getNodeAs<DeclRefExpr>("handler_expr");
-  assert(SignalCall && HandlerDecl && HandlerExpr &&
-         "All of these should exist in a match here.");
-
-  if (CG.size() <= 1) {
-    // Call graph must be populated with the entire TU at the beginning.
-    // (It is possible to add a single function but the functions called from it
-    // are not analysed in this case.)
-    CG.addToCallGraph(const_cast<TranslationUnitDecl *>(
-        HandlerDecl->getTranslationUnitDecl()));
-    assert(CG.size() > 1 &&
-           "There should be at least one function added to call graph.");
-  }
-
-  // Check for special case when the signal handler itself is an unsafe external
-  // function.
-  if (!isFunctionAsyncSafe(HandlerDecl)) {
-    reportBug(HandlerDecl, HandlerExpr, /*DirectHandler=*/true);
-    return;
-  }
-
-  CallGraphNode *HandlerNode = CG.getNode(HandlerDecl);
-  // Signal handler can be external but not unsafe, no call graph in this case.
-  if (!HandlerNode)
-    return;
-  // Start from signal handler and visit every function call.
-  for (auto Itr = llvm::df_begin(HandlerNode), ItrE = llvm::df_end(HandlerNode);
-       Itr != ItrE; ++Itr) {
-    const auto *CallF = dyn_cast<FunctionDecl>((*Itr)->getDecl());
-    if (CallF && !isFunctionAsyncSafe(CallF)) {
-      assert(Itr.getPathLength() >= 2);
-      reportBug(CallF, findCallExpr(Itr.getPath(Itr.getPathLength() - 2), *Itr),
-                /*DirectHandler=*/false);
-      reportHandlerCommon(Itr, SignalCall, HandlerDecl, HandlerExpr);
-    }
-  }
-}
-
-bool SignalHandlerCheck::isFunctionAsyncSafe(const FunctionDecl *FD) const {
-  if (isSystemCall(FD))
-    return isSystemCallAsyncSafe(FD);
-  // For external (not checkable) functions assume that these are unsafe.
-  return FD->hasBody();
-}
-
-bool SignalHandlerCheck::isSystemCallAsyncSafe(const FunctionDecl *FD) const {
-  const IdentifierInfo *II = FD->getIdentifier();
-  // Unnamed functions are not explicitly allowed.
-  if (!II)
-    return false;
-
-  // FIXME: Improve for C++ (check for namespace).
-  if (ConformingFunctions.count(II->getName()))
-    return true;
-
-  return false;
-}
-
-void SignalHandlerCheck::reportBug(const FunctionDecl *CalledFunction,
-                                   const Expr *CallOrRef, bool DirectHandler) {
-  diag(CallOrRef->getBeginLoc(),
-       "%0 may not be asynchronous-safe; %select{calling it from|using it as}1 "
-       "a signal handler may be dangerous")
-      << CalledFunction << DirectHandler;
-}
-
-void SignalHandlerCheck::reportHandlerCommon(
-    llvm::df_iterator<clang::CallGraphNode *> Itr, const CallExpr *SignalCall,
-    const FunctionDecl *HandlerDecl, const Expr *HandlerRef) {
-  int CallLevel = Itr.getPathLength() - 2;
-  assert(CallLevel >= -1 && "Empty iterator?");
-
-  const CallGraphNode *Caller = Itr.getPath(CallLevel + 1), *Callee = nullptr;
-  while (CallLevel >= 0) {
-    Callee = Caller;
-    Caller = Itr.getPath(CallLevel);
-    const Expr *CE = findCallExpr(Caller, Callee);
-    diag(CE->getBeginLoc(), "function %0 called here from %1",
-         DiagnosticIDs::Note)
-        << cast<FunctionDecl>(Callee->getDecl())
-        << cast<FunctionDecl>(Caller->getDecl());
-    --CallLevel;
-  }
-
-  diag(HandlerRef->getBeginLoc(),
-       "function %0 registered here as signal handler", DiagnosticIDs::Note)
-      << HandlerDecl;
-}
-
 // This is the minimal set of safe functions.
 // https://wiki.sei.cmu.edu/confluence/display/c/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers
-llvm::StringSet<> SignalHandlerCheck::MinimalConformingFunctions{
+constexpr std::initializer_list<llvm::StringRef> MinimalConformingFunctions = {
     "signal", "abort", "_Exit", "quick_exit"};
 
 // The POSIX-defined set of safe functions.
@@ -228,7 +22,7 @@ llvm::StringSet<> SignalHandlerCheck::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".
-llvm::StringSet<> SignalHandlerCheck::POSIXConformingFunctions{
+constexpr std::initializer_list<llvm::StringRef> POSIXConformingFunctions = {
     "_Exit",
     "_exit",
     "abort",
@@ -422,6 +216,234 @@ llvm::StringSet<> SignalHandlerCheck::POSIXConformingFunctions{
     "wmemset",
     "write"};
 
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+template <>
+struct OptionEnumMapping<
+    bugprone::SignalHandlerCheck::AsyncSafeFunctionSetKind> {
+  static llvm::ArrayRef<std::pair<
+      bugprone::SignalHandlerCheck::AsyncSafeFunctionSetKind, StringRef>>
+  getEnumMapping() {
+    static constexpr std::pair<
+        bugprone::SignalHandlerCheck::AsyncSafeFunctionSetKind, StringRef>
+        Mapping[] = {
+            {bugprone::SignalHandlerCheck::AsyncSafeFunctionSetKind::Minimal,
+             "minimal"},
+            {bugprone::SignalHandlerCheck::AsyncSafeFunctionSetKind::POSIX,
+             "POSIX"},
+        };
+    return makeArrayRef(Mapping);
+  }
+};
+
+namespace bugprone {
+
+namespace {
+
+/// Returns if a function is declared inside a system header.
+/// These functions are considered to be "standard" (system-provided) library
+/// functions.
+bool isStandardFunction(const FunctionDecl *FD) {
+  // Find a possible redeclaration in system header.
+  // FIXME: Looking at the canonical declaration is not the most exact way
+  // to do this.
+
+  // Most common case will be inclusion directly from a header.
+  // This works fine by using canonical declaration.
+  // a.c
+  // #include <sysheader.h>
+
+  // Next most common case will be extern declaration.
+  // Can't catch this with either approach.
+  // b.c
+  // extern void sysfunc(void);
+
+  // Canonical declaration is the first found declaration, so this works.
+  // c.c
+  // #include <sysheader.h>
+  // extern void sysfunc(void); // redecl won't matter
+
+  // This does not work with canonical declaration.
+  // Probably this is not a frequently used case but may happen (the first
+  // declaration can be in a non-system header for example).
+  // d.c
+  // extern void sysfunc(void); // Canonical declaration, not in system header.
+  // #include <sysheader.h>
+
+  return FD->getASTContext().getSourceManager().isInSystemHeader(
+      FD->getCanonicalDecl()->getLocation());
+}
+
+/// 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
+/// should be deterministic (depend only on the AST).
+Expr *findCallExpr(const CallGraphNode *Caller, const CallGraphNode *Callee) {
+  auto FoundCallee = llvm::find_if(
+      Caller->callees(), [Callee](const CallGraphNode::CallRecord &Call) {
+        return Call.Callee == Callee;
+      });
+  assert(FoundCallee != Caller->end() &&
+         "Callee should be called from the caller function here.");
+  return FoundCallee->CallExpr;
+}
+
+} // namespace
+
+AST_MATCHER(FunctionDecl, isStandardFunction) {
+  return isStandardFunction(&Node);
+}
+
+SignalHandlerCheck::SignalHandlerCheck(StringRef Name,
+                                       ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      AsyncSafeFunctionSet(
+          Options.get("AsyncSafeFunctionSet", AsyncSafeFunctionSetKind::POSIX)),
+      ConformingFunctions(AsyncSafeFunctionSet ==
+                                  AsyncSafeFunctionSetKind::Minimal
+                              ? MinimalConformingFunctions
+                              : POSIXConformingFunctions) {}
+
+void SignalHandlerCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "AsyncSafeFunctionSet", AsyncSafeFunctionSet);
+}
+
+bool SignalHandlerCheck::isLanguageVersionSupported(
+    const LangOptions &LangOpts) const {
+  // FIXME: Make the checker useful on C++ code.
+  if (LangOpts.CPlusPlus)
+    return false;
+
+  return true;
+}
+
+void SignalHandlerCheck::registerMatchers(MatchFinder *Finder) {
+  auto SignalFunction = functionDecl(hasAnyName("::signal", "::std::signal"),
+                                     parameterCountIs(2), isStandardFunction());
+  auto HandlerExpr =
+      declRefExpr(hasDeclaration(functionDecl().bind("handler_decl")),
+                  unless(isExpandedFromMacro("SIG_IGN")),
+                  unless(isExpandedFromMacro("SIG_DFL")))
+          .bind("handler_expr");
+  Finder->addMatcher(
+      callExpr(callee(SignalFunction), hasArgument(1, HandlerExpr))
+          .bind("register_call"),
+      this);
+}
+
+void SignalHandlerCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *SignalCall = Result.Nodes.getNodeAs<CallExpr>("register_call");
+  const auto *HandlerDecl =
+      Result.Nodes.getNodeAs<FunctionDecl>("handler_decl");
+  const auto *HandlerExpr = Result.Nodes.getNodeAs<DeclRefExpr>("handler_expr");
+  assert(SignalCall && HandlerDecl && HandlerExpr &&
+         "All of these should exist in a match here.");
+
+  if (CG.size() <= 1) {
+    // Call graph must be populated with the entire TU at the beginning.
+    // (It is possible to add a single function but the functions called from it
+    // are not analysed in this case.)
+    CG.addToCallGraph(const_cast<TranslationUnitDecl *>(
+        HandlerDecl->getTranslationUnitDecl()));
+    assert(CG.size() > 1 &&
+           "There should be at least one function added to call graph.");
+  }
+
+  if (!HandlerDecl->hasBody()) {
+    (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;
+  }
+
+  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.
+  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) {
+  bool FunctionIsCalled = isa<CallExpr>(CallOrRef);
+
+  if (isStandardFunction(FD)) {
+    if (!isStandardFunctionAsyncSafe(FD)) {
+      diag(CallOrRef->getBeginLoc(), "standard function %0 may not be "
+                                     "asynchronous-safe; "
+                                     "%select{using it as|calling it from}1 "
+                                     "a signal handler may be dangerous")
+          << FD << FunctionIsCalled;
+      return true;
+    }
+    return false;
+  }
+
+  if (!FD->hasBody()) {
+    diag(CallOrRef->getBeginLoc(), "cannot verify that external function %0 is "
+                                   "asynchronous-safe; "
+                                   "%select{using it as|calling it from}1 "
+                                   "a signal handler may be dangerous")
+        << FD << FunctionIsCalled;
+    return true;
+  }
+
+  return false;
+}
+
+bool SignalHandlerCheck::isStandardFunctionAsyncSafe(
+    const FunctionDecl *FD) const {
+  assert(isStandardFunction(FD));
+
+  const IdentifierInfo *II = FD->getIdentifier();
+  // Unnamed functions are not explicitly allowed.
+  if (!II)
+    return false;
+
+  // FIXME: Improve for C++ (check for namespace).
+  if (ConformingFunctions.count(II->getName()))
+    return true;
+
+  return false;
+}
+
+void SignalHandlerCheck::reportHandlerChain(
+    const llvm::df_iterator<clang::CallGraphNode *> &Itr,
+    const DeclRefExpr *HandlerRef) {
+  int CallLevel = Itr.getPathLength() - 2;
+  assert(CallLevel >= -1 && "Empty iterator?");
+
+  const CallGraphNode *Caller = Itr.getPath(CallLevel + 1), *Callee = nullptr;
+  while (CallLevel >= 0) {
+    Callee = Caller;
+    Caller = Itr.getPath(CallLevel);
+    const Expr *CE = findCallExpr(Caller, Callee);
+    diag(CE->getBeginLoc(), "function %0 called here from %1",
+         DiagnosticIDs::Note)
+        << cast<FunctionDecl>(Callee->getDecl())
+        << cast<FunctionDecl>(Caller->getDecl());
+    --CallLevel;
+  }
+
+  diag(HandlerRef->getBeginLoc(),
+       "function %0 registered here as signal handler", DiagnosticIDs::Note)
+      << cast<FunctionDecl>(Caller->getDecl()) << HandlerRef->getSourceRange();
+}
+
 } // namespace bugprone
 } // namespace tidy
 } // namespace clang

diff  --git a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
index dbc7ac85f2c50..f3457d9de3334 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
+++ b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
@@ -24,7 +24,7 @@ namespace bugprone {
 /// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-signal-handler-check.html
 class SignalHandlerCheck : public ClangTidyCheck {
 public:
-  enum class AsyncSafeFunctionSetType { Minimal, POSIX };
+  enum class AsyncSafeFunctionSetKind { Minimal, POSIX };
 
   SignalHandlerCheck(StringRef Name, ClangTidyContext *Context);
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
@@ -33,22 +33,34 @@ class SignalHandlerCheck : public ClangTidyCheck {
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
 private:
-  bool isFunctionAsyncSafe(const FunctionDecl *FD) const;
-  bool isSystemCallAsyncSafe(const FunctionDecl *FD) const;
-  void reportBug(const FunctionDecl *CalledFunction, const Expr *CallOrRef,
-                 bool DirectHandler);
-  void reportHandlerCommon(llvm::df_iterator<clang::CallGraphNode *> Itr,
-                           const CallExpr *SignalCall,
-                           const FunctionDecl *HandlerDecl,
-                           const Expr *HandlerRef);
+  /// Check if a function is allowed as a signal handler.
+  /// 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).
+  /// @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.
+  /// @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
+  /// handler to a function that is called (directly or indirectly) from it.
+  /// Also add a note to the place where the signal handler is registered.
+  /// @param Itr Position during a call graph depth-first iteration. It contains
+  /// the "path" (call chain) from the signal handler to the actual found
+  /// function call.
+  /// @param HandlerRef Reference to the signal handler function where it is
+  /// registered as signal handler.
+  void reportHandlerChain(const llvm::df_iterator<clang::CallGraphNode *> &Itr,
+                          const DeclRefExpr *HandlerRef);
 
   clang::CallGraph CG;
 
-  AsyncSafeFunctionSetType AsyncSafeFunctionSet;
-  llvm::StringSet<> &ConformingFunctions;
-
-  static llvm::StringSet<> MinimalConformingFunctions;
-  static llvm::StringSet<> POSIXConformingFunctions;
+  AsyncSafeFunctionSetKind AsyncSafeFunctionSet;
+  const llvm::StringSet<> ConformingFunctions;
 };
 
 } // namespace bugprone

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler-minimal.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler-minimal.c
index 846079a388dfe..7e88534aeb4b8 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler-minimal.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler-minimal.c
@@ -10,12 +10,12 @@
 
 void handler_bad1(int) {
   _exit(0);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: '_exit' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: standard function '_exit' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
 }
 
 void handler_bad2(void *dst, const void *src) {
   memcpy(dst, src, 10);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'memcpy' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: standard function 'memcpy' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
 }
 
 void handler_good(int) {

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler-posix.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler-posix.c
index 28a69259bd8d0..4fd8e863fd1af 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler-posix.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-handler-posix.c
@@ -11,7 +11,7 @@
 
 void handler_bad(int) {
   printf("1234");
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: standard function 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
 }
 
 void handler_good(int) {

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 10ee3e815adc7..27f431d432a88 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
@@ -5,7 +5,7 @@
 #include "stdio.h"
 #include "system-other.h"
 
-// The function should be classified as system call even if there is
+// The function should be classified as standard function even if there is
 // declaration the in source file.
 // FIXME: The detection works only if the first declaration is in system
 // header.
@@ -17,7 +17,7 @@ void f_extern(void);
 
 void handler_printf(int) {
   printf("1234");
-  // CHECK-NOTES: :[[@LINE-1]]:3: warning: 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // 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,7 +28,7 @@ void test_printf(void) {
 
 void handler_extern(int) {
   f_extern();
-  // CHECK-NOTES: :[[@LINE-1]]:3: warning: 'f_extern' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // 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
 }
@@ -51,7 +51,7 @@ void test_ok(void) {
 
 void f_bad(void) {
   printf("1234");
-  // CHECK-NOTES: :[[@LINE-1]]:3: warning: 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // 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
@@ -67,7 +67,7 @@ void test_bad(void) {
 
 void f_bad1(void) {
   printf("1234");
-  // CHECK-NOTES: :[[@LINE-1]]:3: warning: 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // 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'
@@ -99,7 +99,7 @@ void handler_signal(int) {
 void handler_false_condition(int) {
   if (0)
     printf("1234");
-  // CHECK-NOTES: :[[@LINE-1]]:5: warning: 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // 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
 }
@@ -110,11 +110,11 @@ void test_false_condition(void) {
 
 void handler_multiple_calls(int) {
   f_extern();
-  // CHECK-NOTES: :[[@LINE-1]]:3: warning: 'f_extern' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // 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_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: 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // 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();
@@ -130,17 +130,17 @@ void f_recursive(void);
 void handler_recursive(int) {
   f_recursive();
   printf("");
-  // first 'printf' call (in other function) found only
+  // first 'printf' call (in f_recursive) found only
 }
 
 void f_recursive(void) {
   f_extern();
-  // CHECK-NOTES: :[[@LINE-1]]:3: warning: 'f_extern' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // 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 '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: 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // 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_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
@@ -153,7 +153,7 @@ void test_recursive(void) {
 
 void f_multiple_paths(void) {
   printf("");
-  // CHECK-NOTES: :[[@LINE-1]]:3: warning: 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]
+  // 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
@@ -184,9 +184,9 @@ void test_other(void) {
 
   signal(SIGINT, _Exit);
   signal(SIGINT, other_call);
-  // CHECK-NOTES: :[[@LINE-1]]:18: warning: 'other_call' may not be asynchronous-safe; using it as a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-NOTES: :[[@LINE-1]]:18: warning: standard function 'other_call' may not be asynchronous-safe; using it as a signal handler may be dangerous [bugprone-signal-handler]
   signal(SIGINT, f_extern);
-  // CHECK-NOTES: :[[@LINE-1]]:18: warning: 'f_extern' may not be asynchronous-safe; using it as a signal handler may be dangerous [bugprone-signal-handler]
+  // CHECK-NOTES: :[[@LINE-1]]:18: warning: cannot verify that external function 'f_extern' is asynchronous-safe; using it as a signal handler may be dangerous [bugprone-signal-handler]
 
   signal(SIGINT, SIG_IGN);
   signal(SIGINT, SIG_DFL);


        


More information about the cfe-commits mailing list