[clang-tools-extra] [clang-tidy] Fix false positive in bugprone-use-after-move with std::forward on derived classes (PR #199905)
Baranov Victor via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 1 06:34:30 PDT 2026
================
@@ -1814,3 +1814,46 @@ namespace GH62206 {
(d) = b; // Should not warn
}
} // namespace GH62206
+
+namespace GH63202 {
+
+struct Person {
+ std::string name;
+ Person() = default;
+ Person(Person&&) = default;
+ Person& operator=(Person&&) = default;
+};
+
+struct SpecialPerson : Person {
+ std::string surname;
+
+ // Valid: partial move
+ SpecialPerson(SpecialPerson&& sp)
+ : Person(std::move(sp)), surname(std::move(sp.surname)) {}
+
+ // Valid: partial forward — case fixed by this patch
+ SpecialPerson(SpecialPerson&& sp, int)
+ : Person(std::forward<Person>(sp)), surname(std::move(sp.surname)) {}
+
+ // Invalid: access base class member after base move
+ SpecialPerson(SpecialPerson&& sp, char)
+ : Person(std::move(sp)), surname(std::move(sp.name))
+ // CHECK-NOTES: [[@LINE-1]]:48: warning: 'sp' used after it was moved [bugprone-use-after-move]
+ // CHECK-NOTES: [[@LINE-2]]:7: note: move occurred here
+ {}
+};
+
+void invalidFullMove(SpecialPerson&& sp) {
+ SpecialPerson other(std::move(sp));
+ sp.surname = "1";
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: 'sp' used after it was moved [bugprone-use-after-move]
+ // CHECK-NOTES: [[@LINE-3]]:17: note: move occurred here
+}
+
+void invalidFullForward(SpecialPerson&& sp) {
+ SpecialPerson other(std::forward<SpecialPerson>(sp));
+ sp.surname = "1";
+ // CHECK-NOTES: [[@LINE-1]]:3: warning: 'sp' used after it was forwarded [bugprone-use-after-move]
+ // CHECK-NOTES: [[@LINE-3]]:17: note: forward occurred here
+}
----------------
vbvictor wrote:
Please add tests in template context, like
```cpp
template <typename T>
void partialForwardTemplate(T&& sp) {...}
```
https://github.com/llvm/llvm-project/pull/199905
More information about the cfe-commits
mailing list