https://github.com/AMS21 created https://github.com/llvm/llvm-project/pull/82673
Fixes #82023 >From e1c8ae2d252a4ca9caad5c08faf0b89ae2e15fe9 Mon Sep 17 00:00:00 2001 From: AMS21 <ams21.git...@gmail.com> Date: Thu, 22 Feb 2024 19:24:43 +0100 Subject: [PATCH] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` Fixes #82023 --- .../clang-tidy/bugprone/UseAfterMoveCheck.cpp | 4 +- clang-tools-extra/docs/ReleaseNotes.rst | 4 ++ .../checkers/bugprone/use-after-move.cpp | 37 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index c5b6b541096ca9..f2eaebb7e57833 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -330,7 +330,7 @@ void UseAfterMoveFinder::getReinits( traverse(TK_AsIs, DeclRefMatcher), unless(parmVarDecl(hasType( references(qualType(isConstQualified())))))), - unless(callee(functionDecl(hasName("::std::move"))))))) + unless(callee(functionDecl(hasAnyName("::std::move", "::std::forward"))))))) .bind("reinit"); Stmts->clear(); @@ -388,7 +388,7 @@ void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) { auto TryEmplaceMatcher = cxxMemberCallExpr(callee(cxxMethodDecl(hasName("try_emplace")))); auto CallMoveMatcher = - callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), + callExpr(argumentCountIs(1), callee(functionDecl(hasAnyName("::std::move", "::std::forward"))), hasArgument(0, declRefExpr().bind("arg")), unless(inDecltypeOrTemplateArg()), unless(hasParent(TryEmplaceMatcher)), expr().bind("call-move"), diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a0b9fcfe0d7774..55c47c7617ce2a 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -130,6 +130,10 @@ Changes in existing checks <clang-tidy/checks/bugprone/unused-local-non-trivial-variable>` check by ignoring local variable with ``[maybe_unused]`` attribute. +- Improved :doc:`bugprone-use-after-move + <clang-tidy/checks/bugprone/use-after-move>` check to also handle + calls to ``std::forward``. + - Cleaned up :doc:`cppcoreguidelines-prefer-member-initializer <clang-tidy/checks/cppcoreguidelines/prefer-member-initializer>` by removing enforcement of rule `C.48 diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/use-after-move.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/use-after-move.cpp index 00b1da1e727e4f..0138064ed811b5 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/use-after-move.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/use-after-move.cpp @@ -111,6 +111,18 @@ constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept { return static_cast<typename remove_reference<_Tp>::type &&>(__t); } +template <class _Tp> +constexpr _Tp&& +forward(typename std::remove_reference<_Tp>::type& __t) noexcept { + return static_cast<_Tp&&>(__t); +} + +template <class _Tp> +constexpr _Tp&& +forward(typename std::remove_reference<_Tp>::type&& __t) noexcept { + return static_cast<_Tp&&>(__t); +} + } // namespace std class A { @@ -1525,3 +1537,28 @@ class PR38187 { private: std::string val_; }; + +namespace issue82023 +{ + +struct S { + S(); + S(S&&); +}; + +void consume(S s); + +template <typename T> +void forward(T&& t) { + consume(std::forward<T>(t)); + consume(std::forward<T>(t)); + // CHECK-NOTES: [[@LINE-1]]:27: warning: 't' used after it was moved + // CHECK-NOTES: [[@LINE-3]]:11: note: move occurred here +} + +void create() { + S s; + forward(std::move(s)); +} + +} // namespace issue82023 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits