https://github.com/Discookie updated https://github.com/llvm/llvm-project/pull/162443
>From 147e1a82a3a07f23dee8d1f36185fd477004371d Mon Sep 17 00:00:00 2001 From: Viktor <[email protected]> Date: Wed, 8 Oct 2025 08:48:30 +0000 Subject: [PATCH 1/3] [clang-tidy] Add a fully custom message to `bugprone-unsafe-functions` In some cases, such as when recommending the compiler option _FORTIFY_SOURCE, the current custom message format is clunky. Now, when the reason starts with `>`, the replacement string is omitted., so only the Reason is shown. --- .../clang-tidy/bugprone/UnsafeFunctionsCheck.cpp | 8 +++++++- clang-tools-extra/docs/ReleaseNotes.rst | 5 +++++ .../docs/clang-tidy/checks/bugprone/unsafe-functions.rst | 7 ++++++- .../checkers/bugprone/unsafe-functions-custom.c | 6 +++--- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp index 0399af2a673f4..d24b4998b8bd7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp @@ -304,11 +304,17 @@ void UnsafeFunctionsCheck::check(const MatchFinder::MatchResult &Result) { StringRef Reason = Entry.Reason.empty() ? "is marked as unsafe" : Entry.Reason.c_str(); - if (Entry.Replacement.empty()) { + // 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") diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a94dd9737468c..a4059bdd711e0 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -314,6 +314,11 @@ Changes in existing checks <clang-tidy/checks/bugprone/unhandled-self-assignment>` check by adding an additional matcher that generalizes the copy-and-swap idiom pattern detection. + +- Improved :doc:`bugprone-unsafe-functions + <clang-tidy/checks/bugprone/unsafe-functions>` check by omitting the custom + replacement string, when the Reason starts with the character `>` in the + `CustomFunctions` option. - Improved :doc:`cppcoreguidelines-init-variables <clang-tidy/checks/cppcoreguidelines/init-variables>` check by fixing the diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst index 317db9c5564e2..af6d59fe5c0b4 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst @@ -98,7 +98,9 @@ The `reason` is optional and is used to provide additional information about the reasoning behind the replacement. The default reason is `is marked as unsafe`. If `replacement` is empty, the text `it should not be used` will be shown -instead of the suggestion for a replacement. +instead of the suggestion for a replacement. If the `reason` starts with the +character `>`, the replacement message is disabled, to allow better control over +the suggestions. As an example, the configuration `^original$, replacement, is deprecated;` will produce the following diagnostic message. @@ -114,6 +116,9 @@ qualified name (i.e. ``std::original``), otherwise the regex is matched against If the regular expression starts with `::` (or `^::`), it is matched against the fully qualified name (``::std::original``). +A similar diagnostic message can be printed with the cofiguration +`^original$,,> is deprecated, 'replacement' should be used instead`. + .. note:: Fully qualified names can contain template parameters on certain C++ classes, but not on C++ functions. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions-custom.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions-custom.c index 7fd71ec2f2e7b..7eaf015f06aa2 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions-custom.c +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions-custom.c @@ -1,5 +1,5 @@ // RUN: %check_clang_tidy -check-suffix=NON-STRICT-REGEX %s bugprone-unsafe-functions %t --\ -// RUN: -config="{CheckOptions: {bugprone-unsafe-functions.CustomFunctions: '::name_match,replacement,is a qualname match;^::prefix_match,,is matched on qualname prefix'}}" +// RUN: -config="{CheckOptions: {bugprone-unsafe-functions.CustomFunctions: \"::name_match,,>is a qualname match, but with a fully 'custom' message;^::prefix_match,,is matched on qualname prefix\"}}" // RUN: %check_clang_tidy -check-suffix=STRICT-REGEX %s bugprone-unsafe-functions %t --\ // RUN: -config="{CheckOptions: {bugprone-unsafe-functions.CustomFunctions: '^name_match$,replacement,is matched on function name only;^::prefix_match$,,is a full qualname match'}}" @@ -11,14 +11,14 @@ void prefix_match_regex(); void f1() { name_match(); - // CHECK-MESSAGES-NON-STRICT-REGEX: :[[@LINE-1]]:3: warning: function 'name_match' is a qualname match; 'replacement' should be used instead + // CHECK-MESSAGES-NON-STRICT-REGEX: :[[@LINE-1]]:3: warning: function 'name_match' is a qualname match, but with a fully 'custom' message // CHECK-MESSAGES-STRICT-REGEX: :[[@LINE-2]]:3: warning: function 'name_match' is matched on function name only; 'replacement' should be used instead prefix_match(); // CHECK-MESSAGES-NON-STRICT-REGEX: :[[@LINE-1]]:3: warning: function 'prefix_match' is matched on qualname prefix; it should not be used // CHECK-MESSAGES-STRICT-REGEX: :[[@LINE-2]]:3: warning: function 'prefix_match' is a full qualname match; it should not be used name_match_regex(); - // CHECK-MESSAGES-NON-STRICT-REGEX: :[[@LINE-1]]:3: warning: function 'name_match_regex' is a qualname match; 'replacement' should be used instead + // CHECK-MESSAGES-NON-STRICT-REGEX: :[[@LINE-1]]:3: warning: function 'name_match_regex' is a qualname match, but with a fully 'custom' message // no-warning STRICT-REGEX prefix_match_regex(); >From e3f16b5f3a605a388e254085fc232b598e8689cc Mon Sep 17 00:00:00 2001 From: Viktor <[email protected]> Date: Thu, 16 Oct 2025 08:54:12 +0000 Subject: [PATCH 2/3] Fix typo in release notes --- clang-tools-extra/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a4059bdd711e0..cbd0340fafdec 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -317,7 +317,7 @@ Changes in existing checks - Improved :doc:`bugprone-unsafe-functions <clang-tidy/checks/bugprone/unsafe-functions>` check by omitting the custom - replacement string, when the Reason starts with the character `>` in the + replacement string, when the reason starts with the character `>` in the `CustomFunctions` option. - Improved :doc:`cppcoreguidelines-init-variables >From 28c034981877efdec251109530f8bfdf3802956c Mon Sep 17 00:00:00 2001 From: Viktor <[email protected]> Date: Thu, 30 Oct 2025 13:29:13 +0000 Subject: [PATCH 3/3] Rework docs and add potentially breaking change --- clang-tools-extra/docs/ReleaseNotes.rst | 11 +++- .../checks/bugprone/unsafe-functions.rst | 59 +++++++++++++------ 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index cbd0340fafdec..86be462775417 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -69,6 +69,11 @@ Potentially Breaking Changes - `CharTypdefsToIgnore` to `CharTypedefsToIgnore` in :doc:`bugprone-signed-char-misuse <clang-tidy/checks/bugprone/signed-char-misuse>` + +- Modified the custom message format of :doc:`bugprone-unsafe-functions + <clang-tidy/checks/bugprone/unsafe-functions>` by hiding the default suffix + when the reason starts with the character `>` in the `CustomFunctions` option. + The warning locations are not changed, but the message is different. Improvements to clangd ---------------------- @@ -316,9 +321,9 @@ Changes in existing checks detection. - Improved :doc:`bugprone-unsafe-functions - <clang-tidy/checks/bugprone/unsafe-functions>` check by omitting the custom - replacement string, when the reason starts with the character `>` in the - `CustomFunctions` option. + <clang-tidy/checks/bugprone/unsafe-functions>` check by hiding the default + suffix when the reason starts with the character `>` in the `CustomFunctions` + option. - Improved :doc:`cppcoreguidelines-init-variables <clang-tidy/checks/cppcoreguidelines/init-variables>` check by fixing the diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst index af6d59fe5c0b4..cdaed56442813 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst @@ -80,8 +80,8 @@ including any system headers. Custom functions ---------------- -The option :option:`CustomFunctions` allows the user to define custom functions to be -checked. The format is the following, without newlines: +The option :option:`CustomFunctions` allows the user to define custom functions +to be checked. The format is the following, without newlines: .. code:: @@ -97,38 +97,61 @@ The functions are matched using POSIX extended regular expressions. The `reason` is optional and is used to provide additional information about the reasoning behind the replacement. The default reason is `is marked as unsafe`. -If `replacement` is empty, the text `it should not be used` will be shown -instead of the suggestion for a replacement. If the `reason` starts with the -character `>`, the replacement message is disabled, to allow better control over -the suggestions. +If `replacement` is empty, the default text `it should not be used` will be +shown instead of the suggestion for a replacement. -As an example, the configuration `^original$, replacement, is deprecated;` -will produce the following diagnostic message. +If the `reason` starts with the character `>`, the reason becomes fully custom. +The default suffix is disabled even if a `replacement` is present, and only the +reason message is shown after the matched function, to allow better control over +the suggestions. The starting `>` character and the preceding spaces are trimmed +from the message. + +As an example, the following configuration matches only the function `original` +in the default namespace. A similar diagnostic can also be printed using a fully +custom reason. .. code:: c + + // bugprone-unsafe-functions.CustomFunctions: + // ^original$, replacement, is deprecated; + // Using the fully custom message syntax: + // ^original$,,> is deprecated, 'replacement' should be used instead; - original(); // warning: function 'original' is deprecated; 'replacement' should be used instead. + original(); // warning: function 'original' is deprecated; 'replacement' should be used instead ::std::original(); // no-warning original_function(); // no-warning If the regular expression contains the character `:`, it is matched against the -qualified name (i.e. ``std::original``), otherwise the regex is matched against the unqualified name (``original``). -If the regular expression starts with `::` (or `^::`), it is matched against the -fully qualified name (``::std::original``). +qualified name (i.e. ``std::original``), otherwise the regex is matched against +the unqualified name (``original``). If the regular expression starts with `::` +(or `^::`), it is matched against the fully qualified name +(``::std::original``). + +One of the use cases for fully custom messages is suggesting compiler options +and warning flags: + +.. code:: c + + // bugprone-unsafe-functions.CustomFunctions: + // ^memcpy$,,>is recommended to have compiler hardening using '_FORTIFY_SOURCE'; + // ^printf$,,>is recommended to have the '-Werror=format-security' compiler warning flag; + + memcpy(dest, src, 999'999); // warning: function 'memcpy' is recommended to have compiler hardening using '_FORTIFY_SOURCE' + printf(raw_str); // warning: function 'printf' is recommended to have the '-Werror=format-security' compiler warning flag -A similar diagnostic message can be printed with the cofiguration -`^original$,,> is deprecated, 'replacement' should be used instead`. +The .. note:: - Fully qualified names can contain template parameters on certain C++ classes, but not on C++ functions. - Type aliases are resolved before matching. + Fully qualified names can contain template parameters on certain C++ classes, + but not on C++ functions. Type aliases are resolved before matching. As an example, the member function ``open`` in the class ``std::ifstream`` has a fully qualified name of ``::std::basic_ifstream<char>::open``. - The example could also be matched with the regex ``::std::basic_ifstream<[^>]*>::open``, which matches all potential - template parameters, but does not match nested template classes. + The example could also be matched with the regex + ``::std::basic_ifstream<[^>]*>::open``, which matches all potential template + parameters, but does not match nested template classes. Options ------- _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
