From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id CF55C3893648; Thu, 16 Jul 2020 21:02:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CF55C3893648 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1594933330; bh=Zv8YM61WexyISWCcrIkTazDaVDiM8vq9h4Xlr+zmcGM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=AA4QsO0ZlyCMITCJeHwwMAthns7268dzuB9d2Hp22kdtB0ok2yDZTSMaCeaTtABEO gPWoBP5y1N8GAoTsrr4K19YlSbLkZ2PMOBOLzoJ7ux4F3gPjQhmOIRocaxh460JLfD 6DPYUbPttU6GT533qQx8ka1o/5O9YCXO3lCpw7tY= From: "cvs-commit at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/95599] [coroutines] destructor for temporary operand to co_yield expression called before end of full-expression Date: Thu, 16 Jul 2020 21:02:10 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 10.1.1 X-Bugzilla-Keywords: wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: cvs-commit at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: iains at gcc dot gnu.org X-Bugzilla-Target-Milestone: 10.2 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Jul 2020 21:02:10 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D95599 --- Comment #5 from CVS Commits --- The master branch has been updated by Iain D Sandoe : https://gcc.gnu.org/g:0f66b8486cea8668020e4bd48f261b760cb579be commit r11-2183-g0f66b8486cea8668020e4bd48f261b760cb579be Author: Iain Sandoe Date: Sat Jul 11 08:49:33 2020 +0100 coroutines: Correct frame capture of compiler temps [PR95591+4]. When a full expression contains a co_await (or co_yield), this means that it might be suspended; which would destroy temporary variables (on a stack for example). However the language guarantees that such temporaries are live until the end of the expression. In order to preserve this, we 'promote' temporaries where necessary so that they are saved in the coroutine frame (which allows them to remain live potentially until the frame is destroyed). In addition, sub-expressions that produce control flow (such as TRUTH_AND/OR_IF or COND_EXPR) must be handled specifically to ensure that await expressions are properly expanded. This patch corrects two mistakes in which we were (a) failing to promote some temporaries and (b) we we failing to sequence DTORs for the captures properly. This manifests in a number of related (but not exact duplicate) PRs. The revised code collects the actions into one place and maps all the control flow into one form - a benefit of this is that co_returns are now expanded earlier (which provides an opportunity to address PR95517 in some future patch). We replace a statement that contains await expression(s) with a bind scope that has a variable list describing the temporaries that have been 'promoted' and a statement list that contains a series of cleanup expressions for each of those. Where we encounter nested conditional expressions, these are wrapped in a try-finally block with a guard var for each sub-expression variable that needs a DTOR. The guards are all declared and initialized to false before the first conditional sub- expression. The 'finally' block contains a series of if blocks (one per guard variable) enclosing the relevant DTOR. Variables listed in a bind scope in this manner are automatically moved to a coroutine frame version by existing code (so we re-use that rather than having a separate mechanism). gcc/cp/ChangeLog: PR c++/95591 PR c++/95599 PR c++/95823 PR c++/95824 PR c++/95895 * coroutines.cc (struct coro_ret_data): Delete. (coro_maybe_expand_co_return): Delete. (co_return_expander): Delete. (expand_co_returns): Delete. (co_await_find_in_subtree): Remove unused name. (build_actor_fn): Remove unused parm, remove handling for co_return expansion. (register_await_info): Demote duplicate info message to a warning. (coro_make_frame_entry): Move closer to use site. (struct susp_frame_data): Add fields for final suspend label and a flag to indicate await expressions with initializers. (captures_temporary): Delete. (register_awaits): Remove unused code, update comments. (find_any_await): New. (tmp_target_expr_p): New. (struct interesting): New. (find_interesting_subtree): New. (struct var_nest_node): New. (flatten_await_stmt): New. (handle_nested_conditionals): New. (process_conditional): New. (replace_statement_captures): Rename to... (maybe_promote_temps): ... this. (maybe_promote_captured_temps): Delete. (analyze_expression_awaits): Check for await expressions with initializers. Simplify handling for truth-and/or-if. (expand_one_truth_if): Simplify (map cases that need expansion to COND_EXPR). (await_statement_walker): Handle CO_RETURN_EXPR. Simplify the handling for truth-and/or-if expressions. (register_local_var_uses): Ensure that we create names in the implementation namespace. (morph_fn_to_coro): Add final suspend label to suspend frame callback data and remove it from the build_actor_fn call. gcc/testsuite/ChangeLog: PR c++/95591 PR c++/95599 PR c++/95823 PR c++/95824 PR c++/95895 * g++.dg/coroutines/pr95591.C: New test. * g++.dg/coroutines/pr95599.C: New test. * g++.dg/coroutines/pr95823.C: New test. * g++.dg/coroutines/pr95824.C: New test.=