Index: clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp =================================================================== --- clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp @@ -562,18 +562,24 @@ } static void emitDiagnostic(const Expr *MovingCall, - const ValueDecl *MovedVariable, + const DeclRefExpr *MoveArg, const UseAfterMove &Use, ClangTidyCheck *Check, ASTContext *Context) { - Check->diag(Use.DeclRef->getExprLoc(), "'%0' used after it was moved") - << MovedVariable->getName(); - Check->diag(MovingCall->getExprLoc(), "move occurred here", - DiagnosticIDs::Note); + SourceLocation UseLoc = Use.DeclRef->getExprLoc(); + SourceLocation MoveLoc = MovingCall->getExprLoc(); + + Check->diag(UseLoc, "'%0' used after it was moved") + << MoveArg->getDecl()->getName(); + Check->diag(MoveLoc, "move occurred here", DiagnosticIDs::Note); if (Use.EvaluationOrderUndefined) { - Check->diag(Use.DeclRef->getExprLoc(), + Check->diag(UseLoc, "the use and move are unsequenced, i.e. there is no guarantee " "about the order in which they are evaluated", DiagnosticIDs::Note); + } else if (UseLoc < MoveLoc || Use.DeclRef == MoveArg) { + Check->diag(UseLoc, + "the use happens in a later loop iteration than the move", + DiagnosticIDs::Note); } } @@ -625,8 +631,6 @@ else return; - const ValueDecl *MovedVariable = Arg->getDecl(); - // Ignore the std::move if the variable that was passed to it isn't a local // variable. if (!Arg->getDecl()->getDeclContext()->isFunctionOrMethod()) @@ -634,8 +638,8 @@ UseAfterMoveFinder finder(Result.Context); UseAfterMove Use; - if (finder.find(FunctionBody, MovingCall, MovedVariable, &Use)) - emitDiagnostic(MovingCall, MovedVariable, Use, this, Result.Context); + if (finder.find(FunctionBody, MovingCall, Arg->getDecl(), &Use)) + emitDiagnostic(MovingCall, Arg, Use, this, Result.Context); } } // namespace misc Index: clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp +++ clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp @@ -133,6 +133,7 @@ std::move(a); // CHECK-MESSAGES: [[@LINE-1]]:17: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-2]]:7: note: move occurred here + // CHECK-MESSAGES: [[@LINE-3]]:17: note: the use happens in a later loop } } } @@ -391,7 +392,8 @@ for (int i = 0; i < 10; ++i) { a.foo(); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: 'a' used after it was moved - // CHECK-MESSAGES: [[@LINE+1]]:7: note: move occurred here + // CHECK-MESSAGES: [[@LINE+2]]:7: note: move occurred here + // CHECK-MESSAGES: [[@LINE-3]]:7: note: the use happens in a later loop std::move(a); } } @@ -586,7 +588,7 @@ } } -// Passing the object to a function through a non-const pointer or refernce +// Passing the object to a function through a non-const pointer or reference // counts as a re-initialization. void passByNonConstPointer(A *); void passByNonConstReference(A &);