[clang-tidy] misc-use-after-move: Fix failing assertion

Summary:
I've added a test case that (without the fix) triggers the assertion,
which happens when a move happens in an implicitly called conversion
operator.

Reviewers: alexfh

Reviewed By: alexfh

Subscribers: JDevlieghere, cfe-commits

Differential Revision: https://reviews.llvm.org/D30569

llvm-svn: 297004
This commit is contained in:
Martin Bohme 2017-03-06 08:55:42 +00:00
parent 0243eac2d8
commit a6391ae52b
2 changed files with 17 additions and 2 deletions

View File

@ -398,7 +398,7 @@ void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) {
const auto *MovingCall = Result.Nodes.getNodeAs<Expr>("moving-call");
const auto *Arg = Result.Nodes.getNodeAs<DeclRefExpr>("arg");
if (!MovingCall)
if (!MovingCall || !MovingCall->getExprLoc().isValid())
MovingCall = CallMove;
Stmt *FunctionBody = nullptr;

View File

@ -282,7 +282,7 @@ void moveInInitList() {
S s{std::move(a)};
a.foo();
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'a' used after it was moved
// CHECK-MESSAGES: [[@LINE-3]]:6: note: move occurred here
// CHECK-MESSAGES: [[@LINE-3]]:7: note: move occurred here
}
void lambdas() {
@ -397,6 +397,21 @@ void movedTypeIsDependentType() {
}
template void movedTypeIsDependentType<A>();
// We handle the case correctly where the move consists of an implicit call
// to a conversion operator.
void implicitConversionOperator() {
struct Convertible {
operator A() && { return A(); }
};
void takeA(A a);
Convertible convertible;
takeA(std::move(convertible));
convertible;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'convertible' used after it was moved
// CHECK-MESSAGES: [[@LINE-3]]:9: note: move occurred here
}
// Using decltype on an expression is not a use.
void decltypeIsNotUse() {
A a;