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

--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jason Merrill <ja...@gcc.gnu.org>:

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

commit r12-6327-gce0ab8fb46f07b0bde56aa31e46d57b81379fde3
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu Mar 5 15:50:45 2020 -0500

    c++: temporary lifetime with aggregate init [PR94041]

    In C++98 the lifetime of temporaries in aggregate initialization was
    unclear, but C++11 DR201 clarified that only temporaries created for
    default-initialization of an array element with no corresponding
    initializer-clause are destroyed immediately; all others persist until the
    end of the full-expression.

    But we never implemented that, and continued treating individual element
    initializations as full-expressions, such as in my patch for PR50866 in
    r180442.  This blocked my attempted fix for PR66139, which extended the use
    of split_nonconstant_init, and thus the bug, to aggregate initialization of
    temporaries within an expression.

    The longer temporary lifetime creates further EH region overlap problems
    like the ones that wrap_temporary_cleanups addresses: in aggr7.C, we start
    out with a normal nesting of

    A1
     c.b1
       A2
        c.b2
         ...
       ~A2
    ~A1

    where on the way in, throwing from one of the inits will clean up from the
    previous inits.  But once c.b2 is initialized, throwing from ~A2 must not
    clean up c.b1; instead it needs to clean up c.  So as in build_new_1, we
    deal with this by guarding the B cleanups with flags that are cleared once
c
    is fully constructed; throwing from one of the ~A still hits that region,
    but does not call ~B.  And then wrap_temporary_cleanups deals with calling
    ~C, but we need to tell it not to wrap the subobject cleanups.

    The change from expressing the subobject cleanups with CLEANUP_STMT to
    TARGET_EXPR was also necessary because we need them to collate with the ~A
    in gimplify_cleanup_point_expr; the CLEANUP_STMT representation only worked
    with treating subobject initializations as full-expressions.

            PR c++/94041

    gcc/cp/ChangeLog:

            * decl.c (check_initializer): Remove obsolete comment.
            (wrap_cleanups_r): Don't wrap CLEANUP_EH_ONLY.
            (initialize_local_var): Change assert to test.
            * typeck2.c (maybe_push_temp_cleanup): New.
            (split_nonconstant_init_1): Use it.
            (split_nonconstant_init): Clear cleanup flags.

    gcc/testsuite/ChangeLog:

            * g++.dg/init/aggr7-eh.C: New test.
            * g++.dg/cpp0x/initlist122.C: Also test aggregate variable.

Reply via email to