[clang-tools-extra] [NFC][clang-tidy] Unify diagnostic emission in bugprone-unsafe-functions (PR #194709)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 28 12:46:11 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tidy
Author: Endre Fülöp (gamesh411)
<details>
<summary>Changes</summary>
This patch extracts the three diagnostic forms currently duplicated across the Custom and non-Custom branches of `check()` into a single `emitDiag()` helper.
---
Full diff: https://github.com/llvm/llvm-project/pull/194709.diff
1 Files Affected:
- (modified) clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp (+57-44)
``````````diff
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(
``````````
</details>
https://github.com/llvm/llvm-project/pull/194709
More information about the cfe-commits
mailing list