Closed
Description
Consider the following example:
#include <cstdlib>
#include <cstdio>
struct Abort {
~Abort() {
puts("cleanup");
abort();
}
};
__attribute__((noinline))
static void abort_in_dtor() {
Abort abort;
throw "test";
}
int main() {
try {
abort_in_dtor();
} catch (...) {
puts("caught");
}
}
This should print "cleanup" followed by abort. Instead this happens when using Clang 17:
terminate called after throwing an instance of 'char const*'
Aborted (core dumped)
The reason for this is that we now (correctly) infer that abort_in_dtor()
is nounwind
. However, as phase 1 unwind skips cleanups, this means that the unwind walk will try to go past a nounwind
frame, which may not have an LSDA entry, resulting in some form of unwinding failure. (In this specific case we return _URC_END_OF_STACK
, but a similar case in Rust results in _URC_FATAL_PHASE1_ERROR
.)