diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -158,9 +158,12 @@ // Ignore all reinitializations where the move potentially comes after the // reinit. + // If `Reinit` is identical to `MovingCall`, we're looking at a move-to-self + // (e.g. `a = std::move(a)`). Count these as reinitializations. llvm::SmallVector ReinitsToDelete; for (const Stmt *Reinit : Reinits) { - if (MovingCall && Sequence->potentiallyAfter(MovingCall, Reinit)) + if (MovingCall && Reinit != MovingCall && + Sequence->potentiallyAfter(MovingCall, Reinit)) ReinitsToDelete.push_back(Reinit); } for (const Stmt *Reinit : ReinitsToDelete) { 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 --- 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 @@ -152,6 +152,13 @@ // CHECK-NOTES: [[@LINE-3]]:15: note: move occurred here } +// Don't flag a move-to-self. +void selfMove() { + A a; + a = std::move(a); + a.foo(); +} + // A warning should only be emitted for one use-after-move. void onlyFlagOneUseAfterMove() { A a;