<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/120863>120863</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang-tidy] Check request: don't capture `this` by a field of default copyable class
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang-tidy
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
denzor200
</td>
</tr>
</table>
<pre>
Assume the user defined class:
```
struct A {
std::string content;
std::function<void()> captured;
A() {
captured =
[this]() { // INCORRECT
perform();
};
}
void perform() { std::cout << content << std::endl; }
};
```
Since it's copy constructor was generated by the compiler, it's behaviour might be unexpected for some user and even can produce a crash with SIGSEGV:
```
A a;
a.content = "Hello world";
a.captured();
A a1 = a;
a1.content = "Test";
a1.captured(); // will print "Hello world" which might be unexpected
```
```
auto a = std::make_unique<A>();
a->content = "Hello world";
a->captured();
auto b = std::make_unique<A>(*a);
a.reset();
b->content = "Ooooups!";
b->captured(); // UB
```
The way to fix it is to provide manually written copy constructor and assignment operator:
```
A(const A& oth)
: content(oth.content)
, captured([this](){perform();}) {}
A& operator=(const A& oth) {
if (this != &oth) {
content = oth.content;
captured = [this](){perform();};
}
}
```
Making you class noncopyable also protect you from the bug:
```
A(const A& oth) = delete;
A& operator=(const A& oth) = delete;
```
But before you fix it you must discover it in the code, so the clang-tidy check in bugprone section would be nice addition.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyMVk1z4jgT_jXi0hXKlrENBw4Gknnn8O5UTbJ73ZKtBmsjSx59wLC_fksyNoRwSCoFFuqPp7sfPRazVhwU4prkG5LvZsy7Vps1R_WvNjRJZrXm53Vlre8QXIvgLRrguBcKOTSSWUuyiiQVKZLLf1JZZ3zjoAJSbkhSAYB1PJhlYUuoAzRaOVSOZHF_2t171TihFcm2Ry04oUtCVyR7hob1zhvkFweA4bMaLK55JkMg2S4akXzjWmFJvrvaAqEvhL7A9z-2P37-fN6-XZzHvx7NXptuTL-52Sbl7oqh3IXC43OA-9EvJpoqa7R3QLItybZj8eNyskHFJck2Y9wx021nSVK9CtUgCEdoaaHR_TnEGzquDZyYhQMqNMwhh_ocZ9borhcSDaHb0bHGlh2F9gY6cWgd1Ahe4e8em-C31was7i7TZooDHlFBwxT0RnPfIDBoDLMtnIRr4fX7t9fnb399ZkIFbCiCza9V74BQ-j-UUsNJG8kJpZPROOeb1g9h0ug4Rkvvw72hddc46edA48xPQkrojQiu9yjg1IqmfdSR-zHcPDPvNLCIY5pkx97xb6_EL48k21Yke74tiD2R7Pkr7Yh2jzsSs9Zfylqxa-a5QYvuNlb9AMwPrbXvLaHphKV-iGVs6p8PePrWIpzYGZyGvfgNwoGwYdEbfRQcoWPKMynPcDLCucCuey4H3g361AVwug-s1uYBywhdRscgCAVo1wZ4w6ElWTWpDV1q186n1WRCt3Bb2p1ikHLzSRDK3Sg78awOaSd8u0d4bkRK7IHQZUgCocex6cUnqyhnN4O5xf5Bkz5q3tfQTwGuYvOxp_9n70Goz9oPKg9KqzAhVksEJm0cpMPGRZO90V2UmtofvjifiJajRIcDmq818c7pjnQbHw7uXhscYA3EC4-dtw64sI0-oolsVBdt5BgIYPWwlEwdnpzgZ2habN6DWe0PvdEKwWJ8O8FJe8mDQCgRlJBzEX6ek6Sa8XXGV9mKzXCdltliSfNilc7a9WJZNHW-L8okzZZFlq7YMk-TIsnzDNMUy5lY04QuUkppkiRpls75IilXyyVPFosiL-uaLBLsmJBzKY_dXJvDTFjrcZ3SZFlkM8lqlDa-xim9VhEOcL6bmXXweqr9wZJFIoV19hrHCSfjBeDGLd_BNtZv8JcP2ppVwLUitHQj34AUSaRakYQXDYO9QMlB78P1gHnpYOJLZNDMG7lunevjjSEKx0G41tfzRneEvgQ8l6-n3uh_sHGEvsQiLaEvlzqPa_pfAAAA__96b43i">