https://github.com/AMS21 updated https://github.com/llvm/llvm-project/pull/82673
>From a3729196f3208c4f214ffbfbb28a9a51874a8fd2 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 | 36 +++++++++--------- clang-tools-extra/docs/ReleaseNotes.rst | 4 ++ .../checkers/bugprone/use-after-move.cpp | 37 +++++++++++++++++++ 3 files changed, 60 insertions(+), 17 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index c5b6b541096ca9..a55432cfa3ea4b 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -330,7 +330,8 @@ 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(); @@ -387,22 +388,23 @@ void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) { // the bool. auto TryEmplaceMatcher = cxxMemberCallExpr(callee(cxxMethodDecl(hasName("try_emplace")))); - auto CallMoveMatcher = - callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), - hasArgument(0, declRefExpr().bind("arg")), - unless(inDecltypeOrTemplateArg()), - unless(hasParent(TryEmplaceMatcher)), expr().bind("call-move"), - anyOf(hasAncestor(compoundStmt( - hasParent(lambdaExpr().bind("containing-lambda")))), - hasAncestor(functionDecl(anyOf( - cxxConstructorDecl( - hasAnyConstructorInitializer(withInitializer( - expr(anyOf(equalsBoundNode("call-move"), - hasDescendant(expr( - equalsBoundNode("call-move"))))) - .bind("containing-ctor-init")))) - .bind("containing-ctor"), - functionDecl().bind("containing-func")))))); + auto CallMoveMatcher = callExpr( + argumentCountIs(1), + callee(functionDecl(hasAnyName("::std::move", "::std::forward"))), + hasArgument(0, declRefExpr().bind("arg")), + unless(inDecltypeOrTemplateArg()), unless(hasParent(TryEmplaceMatcher)), + expr().bind("call-move"), + anyOf(hasAncestor(compoundStmt( + hasParent(lambdaExpr().bind("containing-lambda")))), + hasAncestor(functionDecl( + anyOf(cxxConstructorDecl( + hasAnyConstructorInitializer(withInitializer( + expr(anyOf(equalsBoundNode("call-move"), + hasDescendant(expr( + equalsBoundNode("call-move"))))) + .bind("containing-ctor-init")))) + .bind("containing-ctor"), + functionDecl().bind("containing-func")))))); Finder->addMatcher( traverse( 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