[cfe-dev] What's the difference between llvm `resume` instruction and `__cxa_rethrow`?

James Y Knight via cfe-dev cfe-dev at lists.llvm.org
Wed Dec 1 08:26:35 PST 2021


These are indeed different things: IR "resume" is for continuing an
existing in-progress unwind, while "throw;" (aka "call @__cxa_rethrow")
starts a brand new unwind to find a new catch location -- just using the
same exception object.

Thus, you can only use resume to continue on from an intermediate cleanup.
Once you've entered a landingpad having a exception type matching the
"catch" clause, you can no longer resume. See also
https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html -- noting that IR
"resume" ends up as a call to "_Unwind_resume".

Yet, it seems unlikely that Clang is actually getting the above incorrect
-- do you have a more complete test-case you think might be wrong?



On Wed, Dec 1, 2021 at 2:36 AM chuanqi.xcq via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> Hi,
>
>    Recently I am checking the implementation of c++20 coroutine in clang
> and I am wondering if it is possible to mark its status as complete.
> (Now the status is partial althought it's been a while that the clang's
> coroutine is used in production).
>
>    Here is the simple introduction, in the standard:
> https://eel.is/c++draft/dcl.fct.def.coroutine#5, it says both
> initial_suspend().await_ready()
> and initial_suspend().await_suspend() should be wrapped in `try` statement
>  and if there is an exception happens, it would be rethown by
> `throw;` statement. It may look like:
>
> ```C++
> try {
>    auto init_suspend = promise.init_suspend();
>    if (!init_suspend.await_ready())
>         init_suspend.await_suspend();
> } catch (...) {
>     throw;
> }
> ```
>
>     And the implementation didn't wrap them in `try...catch` statement.
> The code generated by clang would look like:
>
> ```LLVM
> invoke promise.init_suspend()
>     to label %cont unwind label %lpad
> invoke init_suspend.await_ready()
>     to label %cont1 unwind label %lpad1
> invoke init_suspend.await_suspend()
>     to label %cont2 unwind label %lpad2
> ...
> %lpad:
>    ...
>    br label %eh.resume
> %lpad1:
>    ...
>    br label %eh.resume
> %lpad2:
>    ...
>    br label %eh.resume
> eh.resume:
>    ....
>    resume
> ```
>
>    And I know that clang would generate `__cxa_rethrow` for `throw;`. I
> did some simple test locally, the behavior now looks
> good for me. (I could catch the exception in the caller of the coroutine). But
> I think it would be better to consult with the experts.
> I am wondering what's the difference and if it would be a block issue for
> conforming clang's implementation.
>
> Thanks,
> Chuanqi
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20211201/1dd61846/attachment.html>


More information about the cfe-dev mailing list