https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83400
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |wrong-code Status|UNCONFIRMED |NEW Last reconfirmed| |2017-12-13 Ever confirmed|0 |1 --- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- Reduced: extern "C" int puts(const char*); struct ThrowInDtor{ ~ThrowInDtor() noexcept(false) { puts("in dtor"); throw 1L; } }; int main() { try { ThrowInDtor throws; throw 1; } catch (int) { // unreachable } } terminate called after throwing an instance of 'int' Aborted (core dumped) The code is misoptimized to: ;; Function int main() (main, funcdef_no=3, decl_uid=2299, cgraph_uid=3, symbol_order=3) (executed once) int main() () { void * _4; void * _11; <bb 2> [100.00%]: _4 = __cxa_allocate_exception (4); MEM[(int *)_4] = 1; __cxa_throw (_4, &_ZTIi, 0B); <L2> [0.00%]: puts ("in dtor"); _11 = __cxa_allocate_exception (8); MEM[(long int *)_11] = 1; __cxa_throw (_11, &_ZTIl, 0B); } It seems the catch(int) has been optimized away and so the destructor never even runs, we just terminate with an uncaught exception.