https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77943
Bug ID: 77943 Summary: Optimization incorrectly commons noexcept calls with non-noexcept calls Product: gcc Version: 6.2.1 Status: UNCONFIRMED Severity: critical Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redbeard0531 at gmail dot com Target Milestone: --- When compiled with -O0 and -01 the program behaves correctly and only calls std::terminate() when passed an argument. With -O2 and -O3 it doesn't call std::terminate() which means that it allowed an exception to escape from a noexcept function in violation of the standard. > g++ -O0 noexcept_test.cpp && ./a.out ; ./a.out 1 should die: 0 should die: 1 terminate called after throwing an instance of 'int' Aborted (core dumped) > g++ -O1 noexcept_test.cpp && ./a.out ; ./a.out 1 should die: 0 should die: 1 terminate called after throwing an instance of 'int' Aborted (core dumped) > g++ -O2 noexcept_test.cpp && ./a.out ; ./a.out 1 should die: 0 should die: 1 > g++ -O3 noexcept_test.cpp && ./a.out ; ./a.out 1 should die: 0 should die: 1 The actual behavior with -O2 and -O3 depends on which way the if block is written. The attached version is the scariest, but if you swap the if and else blocks and remove the ! from the condition, the executable will always call std::terminate() even when it shouldn't.