https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64181
--- Comment #3 from Mikhail Maltsev <miyuki at gcc dot gnu.org> --- A sligtly modified testcase (no templates, no lambdas, inconsistent behavior in single invocation). struct Raiser { virtual void raise() __attribute__((noinline)) { throw 1; } }; struct NoExcept { Raiser *m_raiser; NoExcept(Raiser *raiser) : m_raiser(raiser) { } void call() noexcept { m_raiser->raise(); } }; struct Helper { NoExcept *m_func; Helper(NoExcept *func) : m_func(func) {} virtual void run() __attribute__((noinline)) { m_func->call(); } }; int main() { Raiser raiser; NoExcept noex(&raiser); Helper helper(&noex); try { Helper *volatile ptr_vol = &helper; ptr_vol->run(); } catch (int) { __builtin_printf("Caught int\n"); } try { Helper *ptr = &helper; ptr->run(); } catch (int) { } return 0; } $ g++ -std=c++11 ./test2.cc -O3 -o ./test2 $ ./test2 Caught int terminate called after throwing an instance of 'int' Aborted