[PATCH] D119165: [clang-tidy] Add processing lambda captures at bugprone-use-after-move check
Ivan Murashko via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 7 11:06:51 PST 2022
ivanmurashko created this revision.
ivanmurashko added reviewers: alexfh, sammccall, mboehme, aaron.ballman.
ivanmurashko added projects: clang, clang-tools-extra.
Herald added subscribers: carlosgalvezp, xazax.hun.
ivanmurashko requested review of this revision.
Herald added a subscriber: cfe-commits.
The diff adds processing for `std::move` inside lambda captures at `bugprone-use-after-move` check. Especially it detects invalid `std::move` inside following code
int foo() {
int a = 0;
auto fun = [aa = std::move(a)]{
return aa;
};
return a;
}
Test Plan
./bin/llvm-lit -v ../clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D119165
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
@@ -1350,3 +1350,18 @@
private:
std::string val_;
};
+
+// Check std::move usage inside lambda captures
+int lambdaCaptures() {
+ int a = 0;
+ int b = 0;
+ int c = 0;
+ auto foo = [aa = std::move(a), bb = std::move(b), cc = c] {
+ // CHECK-NOTES: [[@LINE+6]]:10: warning: 'a' used after it was moved
+ // CHECK-NOTES: [[@LINE-2]]:20: note: move occurred here
+ // CHECK-NOTES: [[@LINE+4]]:14: warning: 'b' used after it was moved
+ // CHECK-NOTES: [[@LINE-4]]:39: note: move occurred here
+ return aa + bb + cc;
+ };
+ return a + b + c;
+};
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
@@ -397,11 +397,13 @@
}
void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) {
- auto CallMoveMatcher =
+ auto AncestorMatcher =
+ anyOf(hasAncestor(lambdaExpr().bind("containing-lambda")),
+ hasAncestor(functionDecl().bind("containing-func")));
+
+ auto BaseMoveMatcher =
callExpr(callee(functionDecl(hasName("::std::move"))), argumentCountIs(1),
hasArgument(0, declRefExpr().bind("arg")),
- anyOf(hasAncestor(lambdaExpr().bind("containing-lambda")),
- hasAncestor(functionDecl().bind("containing-func"))),
unless(inDecltypeOrTemplateArg()),
// try_emplace is a common maybe-moving function that returns a
// bool to tell callers whether it moved. Ignore std::move inside
@@ -411,6 +413,16 @@
callee(cxxMethodDecl(hasName("try_emplace")))))))
.bind("call-move");
+ auto CallMoveMatcherLambda = lambdaExpr(
+ forEachLambdaCapture(lambdaCapture(capturesVar(varDecl(
+ hasInitializer(expr(ignoringParenImpCasts(BaseMoveMatcher))))))),
+ AncestorMatcher);
+
+ Finder->addMatcher(CallMoveMatcherLambda, this);
+
+ auto CallMoveMatcherNoLambda =
+ expr(ignoringParenImpCasts(BaseMoveMatcher), AncestorMatcher);
+
Finder->addMatcher(
traverse(
TK_AsIs,
@@ -418,7 +430,7 @@
// for the direct ancestor of the std::move() that isn't one of the
// node types ignored by ignoringParenImpCasts().
stmt(
- forEach(expr(ignoringParenImpCasts(CallMoveMatcher))),
+ forEach(CallMoveMatcherNoLambda),
// Don't allow an InitListExpr to be the moving call. An
// InitListExpr has both a syntactic and a semantic form, and the
// parent-child relationships are different between the two. This
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D119165.406533.patch
Type: text/x-patch
Size: 3021 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220207/5e1f915c/attachment.bin>
More information about the cfe-commits
mailing list