https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109224
Bug ID: 109224 Summary: Wmismatched-new-delete false positive with corotuines Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: rs2740 at gmail dot com Target Milestone: --- #include <coroutine> struct Task { struct promise_type { std::suspend_never initial_suspend() { return {}; } std::suspend_never final_suspend() noexcept { return {}; } void unhandled_exception() { throw; } Task get_return_object() { return {}; } void return_void() {} template<class I> void* operator new(std::size_t sz, I); void operator delete(void* ptr, std::size_t); }; }; Task f(int) { co_return; } int main() { f(42); } g++ -std=c++20 -Wall produces (https://gcc.godbolt.org/z/vjvrPr6dc): <source>: In function 'Task f(int)': <source>:20:1: warning: 'static void Task::promise_type::operator delete(void*, std::size_t)' called on pointer returned from a mismatched allocation function [-Wmismatched-new-delete] 20 | } | ^ <source>:20:1: note: returned from 'static void* Task::promise_type::operator new(std::size_t, I) [with I = int]' 20 | } | ^ This is basically how coroutine frame allocation works (the promise type's operator new can optionally view the coroutine's parameters, while operator delete doesn't). Notably C++23 std::generator does something like this and the reference implementation triggers the same warning. Oddly enough, if operator new is not a template, i.e., operator new(size_t, int), there's no warning.