| Issue |
177890
|
| Summary |
[Clang] Clang sometimes incorrectly makes not-exactly-matching deallocation functions cause ambiguity
|
| Labels |
clang:frontend,
diverges-from:gcc,
diverges-from:msvc
|
| Assignees |
|
| Reporter |
frederick-vs-ja
|
In the following example, both MSVC and GCC doesn't think the deleted deallocation function overloads cause ambiguity and correctly call corresponding deallocation functions when an exception is thrown on initialization. But Clang thinks the deleted overloads cause ambiguity.
Per [[expr.new]/29](https://eel.is/c++draft/expr.new#29), perhaps MSVC and GCC are correct and Clang is wrong.
Link: https://godbolt.org/z/xf4qrqcME
```C++
#include <cstdio>
#include <cstdlib>
#include <new>
template<class...Args>
void operator delete(void*, Args&&...) = delete;
template<class...Args>
void operator delete[](void*, Args&&...) = delete;
struct ThrowingDefaultCtor {
struct UniqueException {};
ThrowingDefaultCtor() { throw UniqueException{}; }
};
void f() {
if (auto p = new (std::nothrow) ThrowingDefaultCtor)
delete p;
}
void g() {
if (auto p = new (std::nothrow) ThrowingDefaultCtor[2])
delete[] p;
}
void* operator new(std::size_t n, const std::nothrow_t&) noexcept { // replacing version
if (n == 0)
++n;
auto p = std::malloc(n);
std::puts("operator new(size_t, nothrow_t)");
return p;
}
void* operator new[](std::size_t n, const std::nothrow_t&) noexcept { // replacing version
if (n == 0)
++n;
auto p = std::malloc(n);
std::puts("operator new[](size_t, nothrow_t)");
return p;
}
void operator delete(void* p) noexcept { // replacing version
std::puts("operator delete(void*)");
std::free(p);
}
void operator delete(void* p, std::size_t) noexcept { // replacing version
std::puts("operator delete(void*, size_t)");
std::free(p);
}
void operator delete(void* p, const std::nothrow_t&) noexcept { // replacing version
std::puts("operator delete(void*, nothrow_t)");
std::free(p);
}
void operator delete[](void* p) noexcept { // replacing version
std::puts("operator delete[](void*)");
std::free(p);
}
void operator delete[](void* p, std::size_t) noexcept { // replacing version
std::puts("operator delete[](void*, size_t)");
std::free(p);
}
void operator delete[](void* p, const std::nothrow_t&) noexcept { // replacing version
std::puts("operator delete[](void*, nothrow_t)");
std::free(p);
}
int main() {
try {
f();
} catch(const ThrowingDefaultCtor::UniqueException&) {
}
try {
g();
} catch(const ThrowingDefaultCtor::UniqueException&) {
}
}
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs