A try { } catch block that calls terminate has no overhead. Normally the constraints on reordering are because e.g. constructor/destructor semantics and other side effects need to be accurately preserved during unwinding, but here any exception is going to result on a call to terminate, and (auto) destructors are not going to run.
This was the entire point of noexcept versus the throw() specifier...
This is unfortunately not always true, even with a table-based unwinder. In order to detect the noexcept frame and call terminate(), the unwinder must be able to see the stack frame that has noexcept. This means that the compiler must suppress tail call optimization when a noexcept function tail calls a non-noexcept function.
This was the entire point of noexcept versus the throw() specifier...