https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100409
--- Comment #13 from Jason Merrill <jason at gcc dot gnu.org> --- (In reply to Richard Biener from comment #3) > - if (! TREE_SIDE_EFFECTS (expr)) > + if (! TREE_SIDE_EFFECTS (expr) && expr_noexcept_p (expr, 0)) > expr = void_node; The assumption that an expression with TREE_SIDE_EFFECTS unset can be discarded if its value is not used is made throughout the compiler. Abandoning that invariant seems like a bad idea. And changing from checking a flag to walking through the whole expression in all of those places sounds like an algorithmic complexity problem. If a pure/const function can throw, fine. But that shouldn't affect how optimization treats the function call, or we'll end up pessimizing the vast majority of calls to pure/const functions that don't throw (but are not explicitly declared noexcept). In this testcase, if the user doesn't want the compiler to optimize away a call to foo(), they shouldn't mark it pure.