<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Coroutine promise types don't support destroying operator delete"
   href="https://bugs.llvm.org/show_bug.cgi?id=48344">48344</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Coroutine promise types don't support destroying operator delete
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++2a
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>cygnus@michiru.ru
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>$ cat pdd.cpp

#if __has_include(<coroutine>)
#include <coroutine>
namespace stdcoro = std;
#else
#include <experimental/coroutine>
namespace stdcoro = std::experimental;
#endif

#include <cstdlib>
#include <new>

struct coroutine
{
    struct promise_type
    {
        coroutine get_return_object() noexcept
        {
            return {*this};
        }

        stdcoro::suspend_always initial_suspend() const noexcept
        {
            return {};
        }

        stdcoro::suspend_always final_suspend() const noexcept
        {
            return {};
        }

        void return_void() const noexcept {}

        void unhandled_exception() noexcept {}

        void* operator new(std::size_t n)
        {
            return std::malloc(n);
        }

        void operator delete(
            promise_type* p,std::destroying_delete_t,std::size_t)
        {
            std::free(p);
        }
    };

    stdcoro::coroutine_handle<promise_type> h_;

    coroutine(promise_type& p)
        : h_{decltype(h_)::from_promise(p)}
    {}

    ~coroutine()
    {
        h_.destroy();
    }
};

coroutine f()
{
    co_return;
}


$ clang++ -std=c++20 -fsyntax-only pdd.cpp

pdd.cpp:59:11: error: too few arguments to function call, expected 3, have 2
coroutine f()
          ^
pdd.cpp:40:14: note: 'operator delete' declared here
        void operator delete(
             ^
1 error generated.


Looking at the end of CoroutineStmtBuilder::makeNewAndDeleteExpr(), it seems
like support for destroying operator delete on promise types is not
implemented.

Neither gcc 10.2 nor MSVC 16.8.2 accept this code with similar error messages,
but it looks like it's impossible to implement a coroutine with statefull
Allocator support for promise that also has access to its allocator in its
implementation without support for this combination. I also can't find anything
that prohibits this in the C++ standard.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>