Bug 111776 - ICE on delete expression with multiple viable destroying operator delete
Summary: ICE on delete expression with multiple viable destroying operator delete
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 13.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2023-10-11 19:58 UTC by Lénárd Szolnoki
Modified: 2023-11-15 10:37 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-10-11 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lénárd Szolnoki 2023-10-11 19:58:39 UTC
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 .
Comment 1 Marek Polacek 2023-10-11 20:08:52 UTC
Confirmed.  even g++9 ICEs.  g++8 gives errors.
Comment 2 Lénárd Szolnoki 2023-10-13 07:54:19 UTC
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
Comment 3 Lénárd Szolnoki 2023-11-15 10:37:24 UTC
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