[clang-tools-extra] [clang-tidy] Add fixit capability to performance-use-std-move linter (PR #184072)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 2 03:45:49 PST 2026
https://github.com/serge-sans-paille updated https://github.com/llvm/llvm-project/pull/184072
>From e21a7eff629765a1c43341699f9125a78cdb7502 Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguelton at mozilla.com>
Date: Mon, 2 Mar 2026 09:01:29 +0100
Subject: [PATCH] [clang-tidy] Add fixit capability to performance-use-std-move
linter
---
.../clang-tidy/performance/UseStdMoveCheck.cpp | 6 +++++-
clang-tools-extra/docs/clang-tidy/checks/list.rst | 2 +-
.../checkers/performance/use-std-move.cpp | 14 ++++++++++++++
3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/performance/UseStdMoveCheck.cpp b/clang-tools-extra/clang-tidy/performance/UseStdMoveCheck.cpp
index d6be91b86eb8c..ecd6a33aa722d 100644
--- a/clang-tools-extra/clang-tidy/performance/UseStdMoveCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UseStdMoveCheck.cpp
@@ -106,8 +106,12 @@ void UseStdMoveCheck::check(const MatchFinder::MatchResult &Result) {
const Stmt *EltStmt = Elt.castAs<CFGStmt>().getStmt();
if (EltStmt == AssignExpr) {
+ const StringRef AssignValueName = AssignValue->getDecl()->getName();
diag(AssignValue->getBeginLoc(), "'%0' could be moved here")
- << AssignValue->getDecl()->getName();
+ << AssignValueName
+ << FixItHint::CreateReplacement(
+ AssignValue->getLocation(),
+ ("std::move(" + AssignValueName + ")").str());
break;
}
// The reference is being referenced after the assignment, bail out.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 24086a4637dbf..4beea34f0c5a6 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -369,7 +369,7 @@ Clang-Tidy Checks
:doc:`performance-type-promotion-in-math-fn <performance/type-promotion-in-math-fn>`, "Yes"
:doc:`performance-unnecessary-copy-initialization <performance/unnecessary-copy-initialization>`, "Yes"
:doc:`performance-unnecessary-value-param <performance/unnecessary-value-param>`, "Yes"
- :doc:`performance-use-std-move <performance/use-std-move>`,
+ :doc:`performance-use-std-move <performance/use-std-move>`, "Yes"
:doc:`portability-avoid-pragma-once <portability/avoid-pragma-once>`,
:doc:`portability-restrict-system-includes <portability/restrict-system-includes>`, "Yes"
:doc:`portability-simd-intrinsics <portability/simd-intrinsics>`,
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/use-std-move.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/use-std-move.cpp
index d823fa75720af..4492d976c37bd 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/use-std-move.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/use-std-move.cpp
@@ -42,6 +42,7 @@ void use(T&) {}
void ConvertibleNonTrivialMoveAssign(NonTrivialMoveAssign& target, NonTrivialMoveAssign source) {
// CHECK-MESSAGES: [[@LINE+1]]:12: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
void NonProfitableNonTrivialMoveAssignPointer(NonTrivialMoveAssign*& target, NonTrivialMoveAssign* source) {
@@ -52,6 +53,7 @@ void NonProfitableNonTrivialMoveAssignPointer(NonTrivialMoveAssign*& target, Non
void ConvertibleNonTrivialMoveAssignFromLValue(NonTrivialMoveAssign& target, NonTrivialMoveAssign&& source) {
// CHECK-MESSAGES: [[@LINE+1]]:12: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
// Check moving already moved values
@@ -74,12 +76,14 @@ struct SomeRecord {
void ConvertibleNonTrivialMoveAssignWithinMethod(NonTrivialMoveAssign& target, NonTrivialMoveAssign source) {
// CHECK-MESSAGES: [[@LINE+1]]:12: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
};
auto ConvertibleNonTrivialMoveAssignWithinLambda = [](NonTrivialMoveAssign& target, NonTrivialMoveAssign source) {
// CHECK-MESSAGES: [[@LINE+1]]:12: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
};
void SomeFunction(NonTrivialMoveAssign source0, NonTrivialMoveAssign const &source1) {
@@ -105,6 +109,7 @@ void ConvertibleNonTrivialMoveAssignShadowing(NonTrivialMoveAssign& target, NoMo
NonTrivialMoveAssign source;
// CHECK-MESSAGES: [[@LINE+1]]:14: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
}
@@ -147,6 +152,7 @@ void NonConvertibleNonTrivialMoveAssignFromConst(NonTrivialMoveAssign& target) {
NonTrivialMoveAssign source;
// CHECK-MESSAGES: [[@LINE+1]]:12: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
void NonConvertibleNonTrivialMoveAssignFromStatic(NonTrivialMoveAssign& target) {
@@ -189,6 +195,7 @@ void ConvertibleNonTrivialMoveAssignToStatic(NonTrivialMoveAssign source) {
static NonTrivialMoveAssign target;
// CHECK-MESSAGES: [[@LINE+1]]:12: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
struct ConvertibleNonTrivialMoveAssignToMember {
@@ -196,6 +203,7 @@ struct ConvertibleNonTrivialMoveAssignToMember {
void NonConvertibleNonTrivialMoveAssignFromStatic(NonTrivialMoveAssign source) {
// CHECK-MESSAGES: [[@LINE+1]]:14: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
};
@@ -203,18 +211,21 @@ void ConvertibleNonTrivialMoveAssignToExtern(NonTrivialMoveAssign source) {
extern NonTrivialMoveAssign target;
// CHECK-MESSAGES: [[@LINE+1]]:12: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
void ConvertibleNonTrivialMoveAssignToTLS(NonTrivialMoveAssign source) {
thread_local NonTrivialMoveAssign target;
// CHECK-MESSAGES: [[@LINE+1]]:12: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
NonTrivialMoveAssign global_target;
void ConvertibleNonTrivialMoveAssignToGlobal(NonTrivialMoveAssign source) {
// CHECK-MESSAGES: [[@LINE+1]]:19: warning: 'source' could be moved here [performance-use-std-move]
global_target = source;
+ // CHECK-FIXES: global_target = std::move(source);
}
void NonConvertibleNonTrivialMoveAssignRValue(NonTrivialMoveAssign& target, NonTrivialMoveAssign const& source) {
@@ -234,6 +245,7 @@ void ConvertibleNonTrivialMoveAssignWithBranching(bool cond, NonTrivialMoveAssig
if(cond) {
// CHECK-MESSAGES: [[@LINE+1]]:14: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
}
@@ -249,11 +261,13 @@ void ConvertibleNonTrivialMoveAssignBothBranches(bool cond, NonTrivialMoveAssign
if(cond) {
// CHECK-MESSAGES: [[@LINE+1]]:14: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
else {
source.stuff();
// CHECK-MESSAGES: [[@LINE+1]]:14: warning: 'source' could be moved here [performance-use-std-move]
target = source;
+ // CHECK-FIXES: target = std::move(source);
}
}
More information about the cfe-commits
mailing list