https://github.com/DimitrijeDobrota updated https://github.com/llvm/llvm-project/pull/138755
>From b6d3a401284022bca317079154764c80b18dcbdd Mon Sep 17 00:00:00 2001 From: Dimitrije Dobrota <m...@dimitrijedobrota.com> Date: Tue, 6 May 2025 22:18:43 +0200 Subject: [PATCH 1/4] Add flag to specify an alternative to std::forward Since std::forward is nothing more than a cast, part of STL and not the language itself, it's easy to provide a custom implementation if one wishes not to include the entirety of <utility>. Added flag (ForwardFunction) provides a way to continue using this essential check even with the custom implementation of forwarding. --- .../cppcoreguidelines/MissingStdForwardCheck.cpp | 11 ++++++++++- .../cppcoreguidelines/MissingStdForwardCheck.h | 7 +++++-- clang-tools-extra/docs/ReleaseNotes.rst | 4 ++++ .../checks/cppcoreguidelines/missing-std-forward.rst | 8 ++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp index cf299609e646d..268b51f76a2c3 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp @@ -120,7 +120,7 @@ void MissingStdForwardCheck::registerMatchers(MatchFinder *Finder) { equalsBoundNode("param"), equalsBoundNode("var")))))), CapturedInLambda)), callee(unresolvedLookupExpr(hasAnyDeclaration( - namedDecl(hasUnderlyingDecl(hasName("::std::forward")))))), + namedDecl(hasUnderlyingDecl(hasName(ForwardFunction)))))), unless(anyOf(hasAncestor(typeLoc()), hasAncestor(expr(hasUnevaluatedContext()))))); @@ -149,4 +149,13 @@ void MissingStdForwardCheck::check(const MatchFinder::MatchResult &Result) { << Param; } +MissingStdForwardCheck::MissingStdForwardCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + ForwardFunction(Options.get("ForwardFunction", "::std::forward")) {} + +void MissingStdForwardCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "ForwardFunction", ForwardFunction); +} + } // namespace clang::tidy::cppcoreguidelines diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.h index 5995ad588855e..f833b8031f8af 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.h @@ -21,8 +21,7 @@ namespace clang::tidy::cppcoreguidelines { /// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/missing-std-forward.html class MissingStdForwardCheck : public ClangTidyCheck { public: - MissingStdForwardCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + MissingStdForwardCheck(StringRef Name, ClangTidyContext *Context); void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { @@ -31,6 +30,10 @@ class MissingStdForwardCheck : public ClangTidyCheck { std::optional<TraversalKind> getCheckTraversalKind() const override { return TK_IgnoreUnlessSpelledInSource; } + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + +private: + const StringRef ForwardFunction; }; } // namespace clang::tidy::cppcoreguidelines diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index e50d40b76e8c4..fdcc51af8ead7 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -327,6 +327,10 @@ Changes in existing checks <clang-tidy/checks/readability/redundant-smartptr-get>` check by fixing some false positives involving smart pointers to arrays. +- Improved :doc:`cppcoreguidelines-missing-std-forward + <clang-tidy/checks/cppcoreguidelines/missing-std-forward>` check by adding a + flag to specify the function used for forwarding instead of ``std::forward``. + Removed checks ^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/missing-std-forward.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/missing-std-forward.rst index 0c311b59a5d5a..d6cc1e53f768d 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/missing-std-forward.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/missing-std-forward.rst @@ -35,6 +35,14 @@ Example: f(1, 2); // Incorrect - may not invoke the desired qualified function operator } +Options +------- + +.. option:: ForwardFunction + + Specify the function used for forwarding. + Default is `::std::forward`. + This check implements `F.19 <http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-forward>`_ from the C++ Core Guidelines. >From af8f4e51678c0c7129e2c3f61d526c89ba237faa Mon Sep 17 00:00:00 2001 From: Dimitrije Dobrota <m...@dimitrijedobrota.com> Date: Mon, 30 Jun 2025 00:00:17 +0200 Subject: [PATCH 2/4] Fix alphabetical order in ReleaseNotes --- clang-tools-extra/docs/ReleaseNotes.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index fdcc51af8ead7..1e2672b388a35 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -212,6 +212,10 @@ Changes in existing checks <clang-tidy/checks/cppcoreguidelines/avoid-goto>` check by adding the option `IgnoreMacros` to ignore ``goto`` labels defined in macros. +- Improved :doc:`cppcoreguidelines-missing-std-forward + <clang-tidy/checks/cppcoreguidelines/missing-std-forward>` check by adding a + flag to specify the function used for forwarding instead of ``std::forward``. + - Improved :doc:`cppcoreguidelines-special-member-functions <clang-tidy/checks/cppcoreguidelines/special-member-functions>` check by adding the option `IgnoreMacros` to ignore classes defined in macros. @@ -327,10 +331,6 @@ Changes in existing checks <clang-tidy/checks/readability/redundant-smartptr-get>` check by fixing some false positives involving smart pointers to arrays. -- Improved :doc:`cppcoreguidelines-missing-std-forward - <clang-tidy/checks/cppcoreguidelines/missing-std-forward>` check by adding a - flag to specify the function used for forwarding instead of ``std::forward``. - Removed checks ^^^^^^^^^^^^^^ >From 65fd4abf0cf6be5dd75c394a487cd1133d0aa5c1 Mon Sep 17 00:00:00 2001 From: Dimitrije Dobrota <m...@dimitrijedobrota.com> Date: Sun, 29 Jun 2025 23:51:36 +0200 Subject: [PATCH 3/4] Add test --- .../missing-std-forward-custom-function.cpp | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/missing-std-forward-custom-function.cpp diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/missing-std-forward-custom-function.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/missing-std-forward-custom-function.cpp new file mode 100644 index 0000000000000..7ccac1a10015f --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/missing-std-forward-custom-function.cpp @@ -0,0 +1,42 @@ +// RUN: %check_clang_tidy -std=c++14 %s cppcoreguidelines-missing-std-forward %t -- \ +// RUN: -config="{CheckOptions: {cppcoreguidelines-missing-std-forward.ForwardFunction: custom_forward}}" -- -fno-delayed-template-parsing + +// NOLINTBEGIN +namespace std { + +template <typename T> struct remove_reference { using type = T; }; +template <typename T> struct remove_reference<T&> { using type = T; }; +template <typename T> struct remove_reference<T&&> { using type = T; }; + +template <typename T> using remove_reference_t = typename remove_reference<T>::type; + +template <typename T> constexpr T &&forward(remove_reference_t<T> &t) noexcept; +template <typename T> constexpr T &&forward(remove_reference_t<T> &&t) noexcept; +template <typename T> constexpr remove_reference_t<T> &&move(T &&x); + +} // namespace std +// NOLINTEND + +template<class T> +constexpr decltype(auto) custom_forward(std::remove_reference_t<T>& tmp) noexcept +{ + return static_cast<T&&>(tmp); +} + +template<class T> +constexpr decltype(auto) custom_forward(std::remove_reference_t<T>&& tmp) noexcept +{ + return static_cast<T&&>(tmp); +} + +template<class T> +void forward_with_std(T&& t) { + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] + + T other{std::forward<T>(t)}; +} + +template<class T> +void move_with_custom(T&& t) { + T other{custom_forward<T>(t)}; +} >From 62bbfbb901c4b8150406012c817654513affae12 Mon Sep 17 00:00:00 2001 From: Dimitrije Dobrota <m...@dimitrijedobrota.com> Date: Mon, 30 Jun 2025 20:04:00 +0200 Subject: [PATCH 4/4] Update clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/missing-std-forward.rst Co-authored-by: EugeneZelenko <eugene.zele...@gmail.com> --- .../checks/cppcoreguidelines/missing-std-forward.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/missing-std-forward.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/missing-std-forward.rst index d6cc1e53f768d..62e38fcd3b9dc 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/missing-std-forward.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/missing-std-forward.rst @@ -40,8 +40,7 @@ Options .. option:: ForwardFunction - Specify the function used for forwarding. - Default is `::std::forward`. + Specify the function used for forwarding. Default is `::std::forward`. This check implements `F.19 <http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-forward>`_ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits