zinovy.nis created this revision. zinovy.nis added reviewers: mboehme, alexfh. zinovy.nis added a project: clang-tools-extra. Herald added subscribers: cfe-commits, mgehre, xazax.hun. Herald added a project: clang.
std::move for const values is NO-OP, so it has no sense to report it in bugprone-use-after-move void simpleConst(const A a) { A other_a = std::move(a); // no actual move takes place here, a.foo(); // so this call is safe and must not be reported. } Anyway, redundant std::move for consts can be found with ```performance-move-const-arg``` check. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D74692 Files: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp 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,14 @@ // CHECK-NOTES: [[@LINE-3]]:15: note: move occurred here } +// Simple case for const value. +void simpleConst(const A a) { + A other_a = std::move(a); + a.foo(); + // CHECK-NOTES-NOT: [[@LINE-1]]:3: warning: 'a' used after it was moved + // CHECK-NOTES-NOT: [[@LINE-3]]:15: note: move occurred here +} + // A warning should only be emitted for one use-after-move. void onlyFlagOneUseAfterMove() { A a; @@ -314,8 +322,8 @@ auto lambda = [a] { std::move(a); 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-NOT: [[@LINE-1]]:7: warning: 'a' used after it was moved + // CHECK-NOTES-NOT: [[@LINE-3]]:7: note: move occurred here }; } // This is just as true if the variable was declared inside the lambda. @@ -721,14 +729,14 @@ const A a; std::move(a); 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-NOT: [[@LINE-1]]:25: warning: 'a' used after it was moved + // CHECK-NOTES-NOT: [[@LINE-3]]:5: note: move occurred here } 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-NOT: [[@LINE-1]]:24: warning: 'a' used after it was moved + // CHECK-NOTES-NOT: [[@LINE-3]]:3: note: move occurred here } // Clearing a standard container using clear() is treated as a 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 @@ -425,13 +425,17 @@ } void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Arg = Result.Nodes.getNodeAs<DeclRefExpr>("arg"); + + if (Arg->getType().isConstQualified()) + return; + const auto *ContainingLambda = Result.Nodes.getNodeAs<LambdaExpr>("containing-lambda"); const auto *ContainingFunc = Result.Nodes.getNodeAs<FunctionDecl>("containing-func"); const auto *CallMove = Result.Nodes.getNodeAs<CallExpr>("call-move"); const auto *MovingCall = Result.Nodes.getNodeAs<Expr>("moving-call"); - const auto *Arg = Result.Nodes.getNodeAs<DeclRefExpr>("arg"); if (!MovingCall || !MovingCall->getExprLoc().isValid()) MovingCall = CallMove;
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,14 @@ // CHECK-NOTES: [[@LINE-3]]:15: note: move occurred here } +// Simple case for const value. +void simpleConst(const A a) { + A other_a = std::move(a); + a.foo(); + // CHECK-NOTES-NOT: [[@LINE-1]]:3: warning: 'a' used after it was moved + // CHECK-NOTES-NOT: [[@LINE-3]]:15: note: move occurred here +} + // A warning should only be emitted for one use-after-move. void onlyFlagOneUseAfterMove() { A a; @@ -314,8 +322,8 @@ auto lambda = [a] { std::move(a); 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-NOT: [[@LINE-1]]:7: warning: 'a' used after it was moved + // CHECK-NOTES-NOT: [[@LINE-3]]:7: note: move occurred here }; } // This is just as true if the variable was declared inside the lambda. @@ -721,14 +729,14 @@ const A a; std::move(a); 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-NOT: [[@LINE-1]]:25: warning: 'a' used after it was moved + // CHECK-NOTES-NOT: [[@LINE-3]]:5: note: move occurred here } 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-NOT: [[@LINE-1]]:24: warning: 'a' used after it was moved + // CHECK-NOTES-NOT: [[@LINE-3]]:3: note: move occurred here } // Clearing a standard container using clear() is treated as a 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 @@ -425,13 +425,17 @@ } void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Arg = Result.Nodes.getNodeAs<DeclRefExpr>("arg"); + + if (Arg->getType().isConstQualified()) + return; + const auto *ContainingLambda = Result.Nodes.getNodeAs<LambdaExpr>("containing-lambda"); const auto *ContainingFunc = Result.Nodes.getNodeAs<FunctionDecl>("containing-func"); const auto *CallMove = Result.Nodes.getNodeAs<CallExpr>("call-move"); const auto *MovingCall = Result.Nodes.getNodeAs<Expr>("moving-call"); - const auto *Arg = Result.Nodes.getNodeAs<DeclRefExpr>("arg"); if (!MovingCall || !MovingCall->getExprLoc().isValid()) MovingCall = CallMove;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits