<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/157500>157500</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
`operator delete(void *, ...)` should not be treated as an usual deallocation function
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ckwastra
</td>
</tr>
</table>
<pre>
Test code ([CE](https://godbolt.org/z/1vzv9vfE7)):
```cpp
#include <cstddef>
struct S {
S();
void *operator new(std::size_t, ...); // OK
// ✅ Clang: OK
// ✅ EDG: OK
// ✅ GCC: OK
// ❌ MSVC: error C2829: 'operator delete' cannot have a variable
// parameter list
void operator delete(void *, ...);
};
void test() {
auto p = new (1, 2, 3) S; // OK
// ❌ Clang: OK
// ✅ GCC: error: no suitable 'operator delete' for 'test1::S'
// ✅ EDG: error: no appropriate operator delete is visible
// ✅ MSVC: error C2573: 'test1::S': cannot delete pointers to objects
// of this type; the class has no non-placement
// overload for 'operator delete'.
// Use::delete, or add 'operator delete(void*)' to the class
delete p;
}
```
According to [N4950, [basic.stc.dynamic.deallocation]/3](https://timsong-cpp.github.io/cppwp/n4950/basic.stc.dynamic.deallocation#3):
> [...] A *usual deallocation function* is a deallocation function whose parameters after the first are
> - optionally, a parameter of type `std::destroying_delete_t`, then
> - optionally, a parameter of type `std::size_t`, then
> - optionally, a parameter of type `std::align_val_t`.
`operator delete(void *, ...)` is not a usual deallocation function. The definition does not mention the possible presence of an ellipsis in function parameters. However, the intent seems clear: in the placement new-expression `new (1, 2, 3) S`, we call `new(std::size_t, ...)` (which is a placement allocation function; see also [CWG2592](https://cplusplus.github.io/CWG/issues/2592.html)); and if `S()` throws, the corresponding `delete(void *, ...)` is called - that is, it is treated as a placement deallocation function. Therefore, `operator delete(void *, ...)` should not be considered in `delete p`, unless we were to admit that it is both a placement deallocation function and a usual deallocation function (which is not permitted by the standard).
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0Vl1z6jgS_TXipQuXkTGGBx74zFZt7e5D7s59TAmpjTUjJJUkw3B__VTbEEhuvmZqJuUkNm6dbp1zupGIUe8t4pyVS1auB6JNjQtz-dtJxBTEYOfUef4NYwLpFALjU1YuVxtWrhmfNin5yIoF41vGt3unds6kzIU949sfjG9Hxx_H2bHeVIzP6CoWLO-uSd5f0nt65IW20rSEX6xkTEphzYpNHxxTaGWCR2DVkuULgEcqgtD6x6PTChhfOI9BJBfA4onxaUyK8hWLqH_gU2J8BVmW9eugLxj-9-8O4fLENpzNVmxawsoIu2fF4t0AgM364eOAh9XqnYA1m64A_vP4SxeAIbgAKz7t-AHGq-eNKDSYkPEKpLDWJWjEEUHAUQQtdgbvkd_58SKIAyYMYHRMN75-yjG90viCKFKgWvc3XUDCmHr6n-UQbXLggRVrYp4cMiIMTn8KCnz8mPGOji8wfiG044turIPY6kREvMNa7QK9oZpHvRceGa8-UfQeX3gfnA9aJHzNGOgIRx31KxnuAF8LXFbFReDXBRWLq8AXbO-0TRgiJAdu9yvKFL-gtashNTpCOnskylODII2IERoRaTvW2aE3QuIBbfoK4BGDcUJdifyZ4uxtlP9H7Ld3DVyBCyCUehOls17nvBmpltyt8g7-SsrNj3cTpJ8RCyldUNruaTUrl_8dz8qc0rJyuRNRyywmmamzFQctM4XCGCdF0s52g2xbvDXPkj5EZ_dD6X2216lpd5l2jG-l9yfP-Nb2SbafJOBF8WL2FRuqilqsXAP5YdHGVhi4XwR1a2W_ekFOE2-_hVPjIt6aPIKoqdeJv1qHmEAEvOQcgvO0RhhzJmbE3Wwg55w9ApvkNDY3nE1zNl32Gj4_KowpuLO2-6dekqdEAvAV5bN_W5rLvP4HkIXRe_t0FKaDz56_i740DCc5CUFNKuADwTL41iAorLXV3QvlsF9GTUcfkDjexW50gA8Y0UqkHQgLaIz2UUfQdyLf5M3gX-6ERwwXaoDGhE0QEQ8RpEHRTS59SXJtdZrLQ_ydckUCZJP8vUnds35CkMKYS-CHX6aTnHBOjZZNb9Rb1rfsXCypWBAmdn26-v7Ayxl_q_ukN22k3xe9t_r-wPhWx9hiZHxLi7MmHcz1gLEEYRXomkq_nhMmOaQmuFO8siZdCBi9s93EYJP8c92JDlQwhNSIBLqD0nQDKaBIqEC83Pz75ghYu9DNxD9hvdi41qjORzvagI1aYUBFWj9vAPxFv9YajJFkPGFAmolCHXS6FN-VvXOp-bzgjs0P_f5CfSrPYzjoRIzszh3bMQmrRFCMz7KBmhdqVszEAOejqqyKcVVMykEz55O8EKqUFZ-oAut6IqZVXiDnKMc7OS4Ges5zXuazfDqa5HxcZiNRTMd8UtWyrmd8V7BxjgehTWbM8UBn0EHnkvmorMo8HxixQxO7Uy7n5P7uLePkvUGY06Lhrt1HNs7ppBRvMEkng_O_rNW9P-xHTA7aYOavTtS986U7ML6lgi7_hj44OhXct8Jln8c5_yMAAP__53OTQw">