[PATCH] D119165: [clang-tidy] Add processing lambda captures at bugprone-use-after-move check
Martin Böhme via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 23 05:58:35 PST 2022
mboehme added inline comments.
================
Comment at: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp:403
hasArgument(0, declRefExpr().bind("arg")),
- anyOf(hasAncestor(lambdaExpr().bind("containing-lambda")),
- hasAncestor(functionDecl().bind("containing-func"))),
----------------
I believe this can be done more simply.
IIUC, the root of the problem is that a std::move() in a lambda capture is being associated with the lambda, when in fact it should be associated with the function that contains the lambda.
This is because the `hasAncestor(lambdaExpr())` matches not just a `std::move` inside the body of the lambda, but also in captures.
I believe this can be solved simply by changing this line so that it only matches a `std::move` inside the body of the lambda, i.e. something like this:
```
hasAncestor(compoundStmt(hasParent(lambdaExpr().bind("containing-lambda"))))
```
This would then no longer match a `std::move` in a capture; the existing logic would instead associate it with the function that contains the lambda.
```
================
Comment at: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp:418
+ forEachLambdaCapture(lambdaCapture(capturesVar(varDecl(
+ hasInitializer(expr(ignoringParenImpCasts(BaseMoveMatcher))))))),
+ AncestorMatcher);
----------------
sammccall wrote:
> This only matches when the initializer is exactly `std::move(x)`.
> Not e.g. if it's `SomeType(std::move(x))`.
>
> Former is probably the common case, but is this deliberate? If we're not sure exactly which cases are safe, maybe add a FIXME?
If this isn't a deliberate restriction, can you add a test for this?
================
Comment at: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp:1355
+// Check std::move usage inside lambda captures
+int lambdaCaptures() {
+ int a = 0;
----------------
Can you put this test with the other tests for lambdas? My suggestion would be to insert it below line 418.
================
Comment at: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp:1356
+int lambdaCaptures() {
+ int a = 0;
+ int b = 0;
----------------
ivanmurashko wrote:
> sammccall wrote:
> > It's pretty interesting that use-after-move fires for ints!
> >
> > Someone might decide to "fix" that though, so probably best to use A like the other tests.
> There is also another case that I want to address as a separate patch.
> ```
> void autoCapture() {
> auto var = [](auto &&res) {
> auto f = [blk = std::move(res)]() {};
> return std::move(res);
> };
> }
> ```
> This one is matched as `UnresolvedLookupExpr` and requires another modified matcher
I assume the reason you don't want to address this case within this particular patch is that it requires a lot of additional code?
================
Comment at: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp:1363
+ // 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;
----------------
Can you put these `CHECK-NOTES` after the line `return a + b + c`?
The other tests put the `CHECK-NOTES` after the use, not the move, and it would be nice to be consistent with that.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D119165/new/
https://reviews.llvm.org/D119165
More information about the cfe-commits
mailing list