version: gcc 13.2.0 flags: -std=c++20 -O2 -pedantic-errors ``` #include <memory> struct B { void operator delete(B* ptr, std::destroying_delete_t); }; struct D : B { void operator delete(D* ptr, std::destroying_delete_t); using B::operator delete; }; void bar(D* ptr) { delete ptr; } ``` internal compiler error: in build_op_delete_call, at cp/call.cc:7914 13 | delete ptr; | ^~~ 0x1ce7bde internal_error(char const*, ...) ???:0 0x7290fc fancy_abort(char const*, int, char const*) ???:0 0x7eb68c build_delete(unsigned int, tree_node*, tree_node*, special_function_kind, int, int, int) ???:0 0x7d3757 delete_sanity(unsigned int, tree_node*, tree_node*, bool, int, int) ???:0 0x89fd5b c_parse_file() ???:0 0x98c5d9 c_common_parse_file() ???:0 https://godbolt.org/z/8rh7h7EWz I'm not entirely sure what should actually happen here. I didn't find a disambiguating rule at https://timsong-cpp.github.io/cppwp/n4868/expr.delete#10 .
Confirmed. even g++9 ICEs. g++8 gives errors.
Same ICE without destroying delete: ``` struct A { void operator delete(void *); }; struct B { void operator delete(void *); }; struct C : A, B { using A::operator delete; using B::operator delete; }; void f(C* ptr) { delete ptr; } ``` This goes back to GCC 7. GCC 6 accepts it and calls `A::operator delete`, which is not much better. https://godbolt.org/z/cczfdKoqb
The C++ standard currently doesn't specify what the behavior of these program snippets are. This is CWG2805. https://cplusplus.github.io/CWG/issues/2805.html