[clang-tools-extra] [clang-tidy] properly handle private move constructors in `modernize-pass-by-value` check (PR #141304)

Baranov Victor via cfe-commits cfe-commits at lists.llvm.org
Sun May 25 04:14:18 PDT 2025


================
@@ -225,8 +257,9 @@ void PassByValueCheck::registerMatchers(MatchFinder *Finder) {
                                   .bind("Param"))))),
                           hasDeclaration(cxxConstructorDecl(
                               isCopyConstructor(), unless(isDeleted()),
-                              hasDeclContext(
-                                  cxxRecordDecl(isMoveConstructible())))))))
+                              hasDeclContext(cxxRecordDecl(
+                                  isMoveConstructibleInBoundCXXRecordDecl(
----------------
vbvictor wrote:

Consider this code:
```cpp
struct Movable {
  int a, b, c;
  Movable() = default;
  Movable(const Movable &) {}
  Movable(Movable &&) {}
};

struct A {
  A(const Movable &M) : M(M) {}
  Movable M;
};
```
In line 236 we bind `struct A` to `outer` so checking it has public move constructor has no use for us.
We need to check that `struct Movable` has move constructor and this is checked in line 261.
Alternatively, I can write here something like
```cpp
hasDeclContext(cxxRecordDecl(
  has(cxxConstructorDecl(
   isMoveConstructor(),
   anyOf(
      isPublic(),
      isFriendOf("outer")) // if we have private ctor but `struct A` is friend of `Movable`
    )))
  ))
```

https://github.com/llvm/llvm-project/pull/141304


More information about the cfe-commits mailing list