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.