-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Description
This was discussed in https://reviews.llvm.org/D108905.
The simple background is:
void bar();
void foo() {
try {
bar();
} catch(...) {}
}
From the perspective of programmers, foo() should be clearly noexcept (although this is not completely correct). And the root cause here is that __cxa_end_catch
is not unwind.
In D108905 we want to make __cxa_end_catch calls nounwind unconditionally. But it gets blocked since the behavior is wrong in certain cases if the destroying exception can throw an exception: https://godbolt.org/z/PYnj85Pdq. Like the case shows, foo()
in the above case is not 100% noexcept. So the current behavior is correct.
However, we know it is really rare that the destroying exception can throw and this problem is relatively important in C++ coroutines. Since C++ coroutines are nearly wrapped in a big try catch generated by compiler:
try {
coroutine function body
} catch (...) {
promise.unhandled_exception()
}
final_suspend: // final suspend is guaranteed to not throw
So if we can make __cxa_end_catch as nounwind, we can make many coroutines as noexcept automatically.
Given the above two reasons (the exceptional case is rare and it is helpful for a lot of functions), I think it makes sense to make __cxa_end_catch calls nounwind conditionally (e.g., by a compilation flag) at least.