https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120243
--- Comment #6 from Iain Sandoe <iains at gcc dot gnu.org> --- a slightly modified testcase (without the lambda, so the dumps are easier to read) #include <coroutine> struct coro { struct promise_type { promise_type() = default; std::suspend_never initial_suspend() const noexcept { __builtin_printf("initial_suspend\n"); return {}; } std::suspend_never final_suspend() const noexcept { return {}; } void unhandled_exception() { __builtin_printf("unhandled_exception\n"); throw; } coro get_return_object() { return {}; } void return_void() {} }; }; coro test () { __builtin_printf("test\n"); throw "hello"; __builtin_abort(); co_return; } int main() { coro C; try { C = test (); } catch(...) { __builtin_printf("Caught!\n"); } } ======= This fails for O2 and passes for O1 The first difference in the dumps is in fixup_cfg3 and the difference is that the actor function gets inlined into the ramp. -fnoinline restores function. GCC-14 does not seem to inline the same case. .. next to figure out how the inlining is breaking the EH.