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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2019-11-07
     Ever confirmed|0                           |1

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The problem is in finalize_nrv_r which does:
  /* Change all cleanups for the NRV to only run when an exception is
     thrown.  */
  else if (TREE_CODE (*tp) == CLEANUP_STMT
           && CLEANUP_DECL (*tp) == dp->var)
    CLEANUP_EH_ONLY (*tp) = 1;
The reason that is done is that when NRV optimizing some variable, we don't
want to run the destructor if the scope is left through return statement,
obviously we still need to run it if exception is thrown, but we need to run
the destructor
also if the scope is left through other means like goto in this testcase;
unfortunately we don't have an IL construct that can do that, we have
TRY_FINALLY_EXPR (coming from CLEANUP_STMT with !CLEANUP_EH_ONLY) where the
cleanup is run always when leaving the scope, and TRY_CATCH_EXPR where the
cleanup is run only when leaving the scope through exceptions.
So, either we need some new construct that would run cleanup whenever not left
through RETURN_EXPR, or need to use TRY_FINALLY_EXPR with some helper bool
variable initialized to something and set to something else right before
RETURN_EXPRs and conditionallize the cleanup on that bool.  The worry here is
whether it could be optimized to whatever we used to emit soon if there are no
gotos and how much worse code it would emit at -O0.

Reply via email to