Index: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -393,6 +393,13 @@ "the use happens in a later loop iteration than the move", DiagnosticIDs::Note); } + if (MoveArg->getType().isConstQualified()) { + SourceLocation MoveArgLoc = MoveArg->getDecl()->getLocation(); + Check->diag(MoveArgLoc, + "std::move of the const expression has no effect; " + "remove std::move() or make the variable non-const", + DiagnosticIDs::Note); + } } void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) { Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp +++ clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp @@ -129,6 +129,16 @@ // CHECK-NOTES: [[@LINE-3]]:15: note: move occurred here } +void simpleConst() { + const A a; + a.foo(); + A other_a = std::move(a); + a.foo(); + // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved + // CHECK-NOTES: [[@LINE-3]]:15: note: move occurred here + // CHECK-NOTES: [[@LINE-6]]:11: note: std::move of the const expression {{.*}} +} + // A warning should only be emitted for one use-after-move. void onlyFlagOneUseAfterMove() { A a; @@ -316,6 +326,7 @@ a.foo(); // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved // CHECK-NOTES: [[@LINE-3]]:7: note: move occurred here + // CHECK-NOTES: [[@LINE-6]]:7: note: std::move of the const expression {{.*}} }; } // This is just as true if the variable was declared inside the lambda. @@ -723,12 +734,14 @@ passByConstPointer(&a); // CHECK-NOTES: [[@LINE-1]]:25: warning: 'a' used after it was moved // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here + // CHECK-NOTES: [[@LINE-5]]:13: note: std::move of the const expression {{.*}} } const A a; std::move(a); passByConstReference(a); // CHECK-NOTES: [[@LINE-1]]:24: warning: 'a' used after it was moved // CHECK-NOTES: [[@LINE-3]]:3: note: move occurred here + // CHECK-NOTES: [[@LINE-5]]:11: note: std::move of the const expression {{.*}} } // Clearing a standard container using clear() is treated as a