<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/146324>146324</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang-tidy] `bugprone-unhandled-self-assignment` doesn't know about allocator arguments to copy/move constructors
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang-tidy
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
MikeWeller
</td>
</tr>
</table>
<pre>
I may have copy/move constructors that take an additional allocator argument (similar to `vector( const vector& other, const Allocator& alloc );`). Additionally, the type may use the [leading-allocator convention](https://en.cppreference.com/w/cpp/memory/uses_allocator.html) with `std::allocator_arg_t`.
If I call one of these "extended" copy/move constructors in my copy/move-and-swap idiom, `bugprone-unhandled-self-assignment` doesn't recognize it and produces a false positive warning (copy-and-swap/move should not trigger the warning).
A rough test:
```
// REQUIRES: static-analyzer
// RUN: clang-tidy -checks='-*,bugprone-unhandled-self-assignment' %s -- | FileCheck %s
namespace std {
namespace pmr {
template <typename TYPE = void>
class allocator {};
}
struct allocator_arg_t {} allocator_arg;
};
#define LEADING_STYLE 1
class MyValueType
{
// pointer member to trigger bugprone-unhandled-self-assignment
void *foo = nullptr;
public:
using allocator_type = std::pmr::allocator<>;
MyValueType(const MyValueType& other)
{
}
#ifdef LEADING_STYLE
MyValueType(std::allocator_arg_t, const allocator_type& alloc, const MyValueType& other)
{
}
#else
MyValueType(const MyValueType& other, const allocator_type& alloc)
{
}
#endif
#ifdef LEADING_STYLE
// CHECK-NOT: warning
MyValueType& operator=(const MyValueType& other)
{
MyValueType tmp(std::allocator_arg, get_allocator(), other);
swap(tmp);
return *this;
}
#else
// CHECK-NOT: warning
MyValueType& operator=(const MyValueType& other)
{
MyValueType tmp(other, get_allocator());
swap(tmp);
return *this;
}
#endif
void swap(MyValueType& other) noexcept {
}
allocator_type get_allocator() const {
return allocator_type();
}
};
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0Vt1u4zYTfRr6ZiBDoSzZvvCF4p_vC7qbtrvZFnsV0OJIYkORAkk56336gpIs2YbTzRZoECAOOTw8c87MmMxaUSjEFYnvSbyZsMaV2qw-ihf8E6VEM9lrflw9QMWOULIDQqbrI6G7SreflXWmyZw2FlzJHDj2gsAUMM6FE1oxCUxKnTGnDTBTNBUqB4QurKiEZAacBpKEB_QYhC46SDj9n4B2JRpC1_1GegLzey0yELok0T1JQkKXU0iHi-XRH3MlgjvW2CbQWGwXSHwvkXGhimBkl2l1QOXPknhD6KJ0rrYkSgndEbpDNc3q2mCOBlWG00xXhO5eCd1lde31wEobL0xj0T4PqNPSVZLQJbwKV_pMreMeM0qHkGdmimdHknBKwpSE6UMOD5AxKUErBJ17xhaBUIrfHCqOnFD6tg1CQXU83w6Y4oF9ZTUILjzrteexb4raaIVBo0qmuEQeWJR50BWEd4kkIXCNVhE6d2Aw04US3xGEA6Y41EbzJkMLDHImLUKtrXDigPDKjBKq8C57GsP9J7q21I3koLQDZ0RRoGlN6Y95FzshUjC6KUpwaJ3XrF30Pne_Ye8MfNr-_uXh0_YziVKwjjmRBUwxefyO5izoy6PfzyRTReAEP0KQlZi9WBJtCJ0HhKaErt-hCp0DobGFIAAyX8NOSFx7oHa146hYhbZmGYJ1HMj8noQpwLhaV2ZYBXBY1ZI5BBKtfaX6OHj6-tsWSLSBgxacRNs-NpPM2rOO8ijzjS9_v-8_tgQAunqAqyLr4y-Xu9MDTCtZxDEXCuHDNt08PP7v-fPT1w9buOu2OxIfj38w2eDTscb2eE-hU7vWQjk0UGG1x7bJT06_Q2GP49MGQtNc61YG1UhZOzNQBKibvRRZVxdemsb6mhsza5veHx06rq7MVeuRaO21HUDPc_LF6yfOxdowj5b9raONg_iERiLnmF-K10dd3vDmMBjm3WU-w9AbA36SHo1QWrxJ5p_wfkjn6sLxNsVF_g5d-rpZ_3-7_iV4_PXJ9-ppIFwbk4Cu0XT-bX7ap6vEwVX1m074xAt04zgndOEx6XrEj86BuzG3aDFPWwZdY5QvZlcKO8bfcuQHMlx79l8oMTh-M_F35Nv_3Ez7Vl344Lbde7A36IPS-C3D2t3queu-v8G9r-DL9HuS12W9GLPprxim4_nXT5hO-Criy2jJJri6m8d3dJ7MF3RSrmaL_V2MfB7zJA6TfRTm82wfR7NsGeWzfBlNxIqGNA6TKAyXs4TS6R3dJ0nMkEVhtlgiJ7MQKybkVMpDNdWmmAhrG1zdzZKIziaS7VHa9tlG6fitRij1zziz8qeCfVNYMgulsM6OOE442T74zo7Fm3_zKHhR-hXYXjfuxivP-rH_1jNl0hi5unxhFcKVzb5_WHmy_Z-gNvovzByhu1YBS-iuF-Gwon8HAAD__54pXgY">