Author: Endre Fülöp
Date: 2026-05-12T15:24:25+02:00
New Revision: 6d22e10845e43897eadab44631eb785170b41d92

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

LOG: [NFC][clang-tidy] Unify diagnostic emission in bugprone-unsafe-functions 
(#194709)

This patch extracts the three diagnostic forms currently duplicated
across the Custom and non-Custom branches of `check()` into a single
`emitDiag()` helper.

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index d87511b6bdd73..936fb991c5fff 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
@@ -249,6 +249,29 @@ void UnsafeFunctionsCheck::registerMatchers(MatchFinder 
*Finder) {
   }
 }
 
+/// A ``Reason`` prefixed with ``>`` produces a fully-custom message and
+/// suppresses the ``Replacement`` suffix; an empty ``Replacement`` yields
+/// the "it should not be used" form; otherwise the standard suggestion
+/// form is used.
+static void emitDiag(ClangTidyCheck &Check, const Expr *SourceExpr,
+                     const FunctionDecl *FuncDecl, StringRef Replacement,
+                     StringRef Reason) {
+  if (Reason.consume_front(">")) {
+    Check.diag(SourceExpr->getExprLoc(), "function %0 %1")
+        << FuncDecl << Reason.trim() << SourceExpr->getSourceRange();
+    return;
+  }
+  if (Replacement.empty()) {
+    Check.diag(SourceExpr->getExprLoc(),
+               "function %0 %1; it should not be used")
+        << FuncDecl << Reason << SourceExpr->getSourceRange();
+    return;
+  }
+  Check.diag(SourceExpr->getExprLoc(),
+             "function %0 %1; '%2' should be used instead")
+      << FuncDecl << Reason << Replacement << SourceExpr->getSourceRange();
+}
+
 void UnsafeFunctionsCheck::check(const MatchFinder::MatchResult &Result) {
   const Expr *SourceExpr = nullptr;
   const FunctionDecl *FuncDecl = nullptr;
@@ -282,60 +305,50 @@ void UnsafeFunctionsCheck::check(const 
MatchFinder::MatchResult &Result) {
       isAnnexKAvailable(IsAnnexKAvailable, PP, getLangOpts());
   StringRef FunctionName = FuncDecl->getName();
 
+  std::string Replacement;
+  std::string Reason;
+
   if (Custom) {
+    const CheckedFunction *MatchedEntry = nullptr;
     for (const auto &Entry : CustomFunctions) {
       if (Entry.Pattern.match(*FuncDecl)) {
-        StringRef Reason =
-            Entry.Reason.empty() ? "is marked as unsafe" : 
Entry.Reason.c_str();
-
-        // Omit the replacement, when a fully-custom reason is given.
-        if (Reason.consume_front(">")) {
-          diag(SourceExpr->getExprLoc(), "function %0 %1")
-              << FuncDecl << Reason.trim() << SourceExpr->getSourceRange();
-          // Do not recommend a replacement when it is not present.
-        } else if (Entry.Replacement.empty()) {
-          diag(SourceExpr->getExprLoc(),
-               "function %0 %1; it should not be used")
-              << FuncDecl << Reason << Entry.Replacement
-              << SourceExpr->getSourceRange();
-          // Otherwise, emit the replacement.
-        } else {
-          diag(SourceExpr->getExprLoc(),
-               "function %0 %1; '%2' should be used instead")
-              << FuncDecl << Reason << Entry.Replacement
-              << SourceExpr->getSourceRange();
-        }
-
-        return;
+        MatchedEntry = &Entry;
+        break;
       }
     }
-
-    llvm_unreachable("No custom function was matched.");
-    return;
-  }
-
-  const std::optional<std::string> ReplacementFunctionName =
-      [&]() -> std::optional<std::string> {
-    if (AnnexK) {
-      if (AnnexKIsAvailable)
-        return getAnnexKReplacementFor(FunctionName);
-      return std::nullopt;
+    if (!MatchedEntry) {
+      llvm_unreachable("No custom function was matched.");
+      return;
     }
+    Replacement = MatchedEntry->Replacement;
+    Reason = MatchedEntry->Reason.empty() ? "is marked as unsafe"
+                                          : MatchedEntry->Reason;
+  } else {
+    const std::optional<std::string> ReplacementFunctionName =
+        [&]() -> std::optional<std::string> {
+      if (AnnexK) {
+        if (AnnexKIsAvailable)
+          return getAnnexKReplacementFor(FunctionName);
+        return std::nullopt;
+      }
 
-    if (Normal)
-      return getReplacementFor(FunctionName, AnnexKIsAvailable).str();
+      if (Normal)
+        return getReplacementFor(FunctionName, AnnexKIsAvailable).str();
 
-    if (Additional)
-      return getReplacementForAdditional(FunctionName, 
AnnexKIsAvailable).str();
+      if (Additional)
+        return getReplacementForAdditional(FunctionName, AnnexKIsAvailable)
+            .str();
 
-    llvm_unreachable("Unhandled match category");
-  }();
-  if (!ReplacementFunctionName)
-    return;
+      llvm_unreachable("Unhandled match category");
+    }();
+    if (!ReplacementFunctionName)
+      return;
+
+    Replacement = *ReplacementFunctionName;
+    Reason = getRationaleFor(FunctionName).str();
+  }
 
-  diag(SourceExpr->getExprLoc(), "function %0 %1; '%2' should be used instead")
-      << FuncDecl << getRationaleFor(FunctionName)
-      << ReplacementFunctionName.value() << SourceExpr->getSourceRange();
+  emitDiag(*this, SourceExpr, FuncDecl, Replacement, Reason);
 }
 
 void UnsafeFunctionsCheck::registerPPCallbacks(


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to