This test: #include <iostream> #include <stdexcept> #include <exception> #include <cstdlib> void handler1() { std::cout << "handler 1\n"; std::abort(); } void handler2() { std::cout << "handler 2\n"; std::abort(); } struct A { ~A() {std::set_terminate(handler2);} }; void f2() { std::set_terminate(handler1); throw std::runtime_error("throw in f2"); } void f1() noexcept { A a; f2(); } int main() { f1(); } Should output: handler 1 When run against the trunk libc++abi. Note that the trunk libc++abi won't run with the trunk libc++, but this will change soon (within a few days). When the noexcept is violated, clang currently outputs a call to std::terminate(). Just prior to that call clang needs to call __cxa_begin_catch(unwind_arg) to make this work. Reference [except.handle]/p7: Also, an implicit handler is considered active when std::terminate() or std::unexpected() is entered due to a throw. With the Itanium ABI, the way you make a handler active is by calling __cxa_begin_catch(unwind_arg).
I'm just now noticing that we have the same issue when ever clang calls terminate for *any* reason during stack unwinding. I.e. if a cleanup section throws when it shouldn't, and clang calls terminate, call __cxa_begin_catch first!
I see what you're saying, but for what it's worth, I think every existing compiler does this. You might just want to make std::terminate more robust.
How?
Do you not already track the exception curently being thrown? I suppose you don't.
Fixed in r174939, r174940, and r184475.