https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90029
Bug ID: 90029 Summary: optimizing local exceptions, or are they an observable side effect Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: federico.kircheis at gmail dot com Target Milestone: --- Hello, this is partly a question, and partly a feature request Consider following functions ---- int bar_ex_noexcept(int i) noexcept { struct foo{}; try { if(i<0){ throw foo{}; } return i; }catch(foo){ return -1; } } int bar_ex(int i) { struct foo{}; try { if(i<0){ throw foo{}; } return i; }catch(foo){ return -1; } } int bar_ret(int i) noexcept { if(i<0){ return -1; } return i; } int bar_goto(int i) noexcept { if(i<0){ goto ex; } return i; ex: return -1; } ---- All this functions, unless I overlooked something, do exactly the same with different control structure (goto, exception, early return): return the given value i positive or 0, -1 if less than 0. gcc is smart, and all functions, except those that use as implementation detail an exception, generate the same assembly with (testing with `-O3`). `bar_ex_noexcept` also has a call to `std::terminate`, even if it will never get executed (example here: https://godbolt.org/z/XVtgXG). Since `foo` is defined locally to `bar_ex`/`bar_ex_noexcept`, I expected that gcc would have been able to optimize the throw and catch clause completely (calls to `__cxa_allocate_exception` and `__cxa_throw`), but it's not the case. Also the conditional call to `std::terminate` in `bar_ex_noexcept` surprised me, since the only thrown exception is always caught and ignored. Therefore my question: are exceptions an observable behavior, and thus the compiler can't optimize them completely away, or is simply gcc "not smart enough" to do those optimization. If they are not observable, the feature request would be to * optimize local exceptions * thus remove typeinfo information for types that can never escape the local scope (since if the exceptions are optimized, those information are not used by anyone) * remove dead calls to `std::terminate`