https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97720
--- Comment #5 from Jason Merrill <jason at gcc dot gnu.org> --- Note that Foo is unneeded, this shows the same behavior: void bad_guy() throw() { try { throw 0; } catch (float) { } // Don't catch int. } void level1() { bad_guy(); throw "dead code"; } int main() { try { level1(); } catch (int) { } } // terminate called without an active exception Without the throw "dead code" the compiler optimizes away the catch in main, so the handler search finds nothing, so __cxa_throw calls __cxa_call_terminate and std::current_exception is set properly. But of course the catch in main shouldn't make a difference, the search should never leave bad_guy.