[Bug c++/100409] C++ FE elides pure throwing call

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Jul 8 14:09:02 GMT 2021


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100409

--- Comment #14 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jason Merrill from comment #13)
> (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.

Hmm, fair enough.  Does that mean C++ should default to
-fdelete-dead-exceptions?

Elsewhere it's said that TREE_SIDE_EFFECTS, const/pure and EH are orthogonal
concepts but yes, that we have to walk expressions recursively to figure
nothrow sucks.  Though the convert_to_void "optimization" could be seen
as premature, on GIMPLE there's no recursive walking needed and nothrow
discovery should discover nothrow-ness of most small functions that have
the body available - so the other option I considered was to remove
that optimization.

Now, this C++ decision makes my life a bit harder (writing testcases for
the middle-end issues around throwing pure/const functions).


More information about the Gcc-bugs mailing list