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.

Reply via email to