[PATCH] D115219: [C++20] [Coroutines] Mark coroutine done if unhandled_exception throws

Chuanqi Xu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 6 22:15:09 PST 2021


ChuanqiXu created this revision.
ChuanqiXu added reviewers: rjmccall, lxfind, junparser, ychen, aaron.ballman.
ChuanqiXu added projects: clang, LLVM.
Herald added a subscriber: hiraditya.
ChuanqiXu requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, jdoerfert.

[[dcl.fct.def.coroutine]/p14](https://eel.is/c++draft/dcl.fct.def.coroutine#14) says:

> If the evaluation of the expression promise.unhandled_­exception() exits via an exception, the coroutine is considered suspended at the final suspend point.

However, this is not implemented in clang. We could observe this from: https://godbolt.org/z/Edr59d5Y6.

This patch tries to implement [dcl.fct.def.coroutine]/p14 by rewrite the call to `promise.unhandled_exception()` into:

  C++
  try {
      promise.unhandled_exception();
  } catch(...) {
      __builtin_coro_mark_done();
      throw;
  }

And this patch introduces another coroutine intrinsic: `llvm.coro.mark.done()`. This would mark the coroutine done (suspended at the final suspend). Previously, this is done by the call to `llvm.coro.suspend(frame, /*IsFinal=*/true)`. There are two reasons why I choose to create a new intrinsic:

- The semantic isn't correct if we try to use `llvm.coro.suspend(, /*IsFinal=*/true)`. First, there is nothing to suspend. Second, `llvm.coro.suspend` has more semantics than `llvm.coro.mark.done`. So it seems inappropriate to reuse `llvm.coro.suspend`.
- The implementation would be more simple and robust if we use new intrinsics. There are codes treating `llvm.coro.suspend` specially. It is necessary to construct the structure  of the coroutine. And it would be complicated if we reuse `llvm.coro.suspend(, /*IsFinal*/true)` in an inappropriate place.

After this patch, the behavior of this example would be the same with GCC: https://godbolt.org/z/rh86xKf85.

Test Plan: check-all,  https://godbolt.org/z/rh86xKf85 and an internal coroutine library


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115219

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/test/CodeGenCoroutines/coro-await-resume-eh-exp-namespace.cpp
  clang/test/CodeGenCoroutines/coro-await-resume-eh.cpp
  clang/test/CodeGenCoroutines/coro-throw-from-unhandled_exception.cpp
  llvm/docs/Coroutines.rst
  llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/Transforms/Coroutines/CoroInstr.h
  llvm/lib/Transforms/Coroutines/CoroInternal.h
  llvm/lib/Transforms/Coroutines/CoroSplit.cpp
  llvm/lib/Transforms/Coroutines/Coroutines.cpp
  llvm/test/Transforms/Coroutines/coro-mark-done.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D115219.392265.patch
Type: text/x-patch
Size: 15186 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211207/13b3d0b2/attachment-0001.bin>


More information about the cfe-commits mailing list