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

--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Jason Merrill <[email protected]>:

https://gcc.gnu.org/g:e8207be46a6ebbbc079adc72c763b648de5c2da5

commit r17-4499-ge8207be46a6ebbbc079adc72c763b648de5c2da5
Author: Joshua Berne <[email protected]>
Date:   Mon Sep 21 00:09:58 2026 +0100

    c++: fix return object cleanup for functions with contracts [PR127281]

    PR c++/127281 - [c++26][contracts] a contract emits the return-value
cleanup
    twice: returned object destroyed twice, and an ICE in gimple_add_tmp_var

    In maybe_apply_function_contracts we create an artificial block that will
    contain the contract assertion evaluations, much like a function try block.
    This, however, runs after the function body has already been processed,
    a declaration for the return value sentinel has already been added (if
    needed), and cleanup code for the return value is already in place. 
Running
    maybe_splice_retval_cleanup again when the artificial block completes
    will crash due to multiple declarations of the sentinel, and if that is
    fixed it will double-destroy a non-trivial return value.

    Tests that hit this bug were added to an existing test case that handles
    non-trivial return types, and that test was generally enhanced to also
    execute at runtime (with no violations of any contract assertions, just
    code generation for them) in order to identify the cases where objects
    are double-destroyed (or leaked).

    To fix this, override current_retval_sentinel for the contracts
    artificial block.  Note that there is still a lingering issue
    (PR c++/127414) involving destruction of the return value when the
    postcondition evaluations exit via an exception, but that fix is more
    involved and depends on this one rather than overlapping it.

            PR c++/127281

    gcc/cp/ChangeLog:

            * contracts.cc (maybe_apply_function_contracts): Override
            current_retval_sentinel for the artificial block containing
            contracts.

    gcc/testsuite/ChangeLog:

            * g++.dg/contracts/cpp26/dcl.contract.res.p1-NT.C: Added runtime
            testing, along with tests of NRVO and exceptions from local
            variables.

    Signed-off-by: Joshua Berne <[email protected]>

Reply via email to