From patchwork Mon Mar 13 06:57:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Arsen_Arsenovi=C4=87?= X-Patchwork-Id: 66285 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 46B0C3858426 for ; Mon, 13 Mar 2023 06:59:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 46B0C3858426 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1678690755; bh=ATGYgkdu+DJ7YdoE6rgP3nfWFSCUKb3GP0fMIvQXVac=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=hAZvBpkZ4s9wG+GXltuTQt1O0Bcszn15B8grimRjaEuFIPu36tSbvl79Nh5ARK3C1 fmVIBHe25HPpBH7LxZhPeuaPokqh2Gvc74TgwkNgg8GD1GChEThB8lMlajneBjqh2B hIPT3IbPGhisfHm7DPu1+/fxzlHq6CuAxRoLQIFc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-103.mailbox.org (mout-p-103.mailbox.org [80.241.56.161]) by sourceware.org (Postfix) with ESMTPS id A14903858D39 for ; Mon, 13 Mar 2023 06:58:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A14903858D39 Received: from smtp2.mailbox.org (smtp2.mailbox.org [IPv6:2001:67c:2050:b231:465::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-103.mailbox.org (Postfix) with ESMTPS id 4PZnYs4r7gz9smD; Mon, 13 Mar 2023 07:58:41 +0100 (CET) To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , =?utf-8?q?Arsen_Arsenovi=C4=87?= Subject: [PATCH gcc-{11, 12}] c++: top level bind when rewriting coroutines [PR106188] Date: Mon, 13 Mar 2023 07:57:43 +0100 Message-Id: <20230313065742.1335925-1-arsen@aarsen.me> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4PZnYs4r7gz9smD X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_INFOUSMEBIZ, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: =?utf-8?q?Arsen_Arsenovi=C4=87_via_Gcc-patches?= From: =?utf-8?q?Arsen_Arsenovi=C4=87?= Reply-To: =?utf-8?q?Arsen_Arsenovi=C4=87?= Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" In the edge case of a coroutine not containing any locals, the ifcd/switch temporaries would get added to the coroutine frame, corrupting its layout. To prevent this, we can make sure there is always a BIND_EXPR at the top of the function body, and thus, always a place for our new temporaries to go without interfering with the coroutine frame. PR c++/106188 - Incorrect frame layout after transforming conditional statement without top-level bind expression PR c++/106713 - if (co_await ...) crashes with a jump to ud2 PR c++/106188 PR c++/106713 gcc/cp/ChangeLog: * coroutines.cc (coro_rewrite_function_body): Ensure we have a BIND_EXPR wrapping the function body. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr106188.C: New test. --- Morning, A while back, we merged this patch into GCC 13 to fix PR106188, but never backported it into GCC 11 and 12, which both still suffer from this bug. I've tested the same patch against releases/gcc-{11,12} and they apply and fix the testcase (and the testcase fails without them, as expected) on x86_64-pc-linux-gnu. OK for backporting? Thanks in advance. gcc/cp/coroutines.cc | 9 ++++++ gcc/testsuite/g++.dg/coroutines/pr106188.C | 34 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 gcc/testsuite/g++.dg/coroutines/pr106188.C diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index e982cdb89a7..ea3850082cf 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -4067,6 +4067,15 @@ coro_rewrite_function_body (location_t fn_start, tree fnbody, tree orig, BLOCK_SUPERCONTEXT (replace_blk) = top_block; BLOCK_SUBBLOCKS (top_block) = replace_blk; } + else + { + /* We are missing a top level BIND_EXPR. We need one to ensure that we + don't shuffle around the coroutine frame and corrupt it. */ + tree bind_wrap = build3_loc (fn_start, BIND_EXPR, void_type_node, + NULL, NULL, NULL); + BIND_EXPR_BODY (bind_wrap) = fnbody; + fnbody = bind_wrap; + } /* Wrap the function body in a try {} catch (...) {} block, if exceptions are enabled. */ diff --git a/gcc/testsuite/g++.dg/coroutines/pr106188.C b/gcc/testsuite/g++.dg/coroutines/pr106188.C new file mode 100644 index 00000000000..9db3778d079 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr106188.C @@ -0,0 +1,34 @@ +// { dg-do run { target c++20 } } +// test case from pr106188, w/o workaround +#include + +struct task { + struct promise_type { + task get_return_object() { return task{}; } + void return_void() {} + void unhandled_exception() {} + auto initial_suspend() noexcept { return std::suspend_never{}; } + auto final_suspend() noexcept { return std::suspend_never{}; } + }; +}; + +struct suspend_and_resume { + bool await_ready() const { return false; } + void await_suspend(std::coroutine_handle<> h) { h.resume(); } + void await_resume() {} +}; + +task f() { + if (co_await suspend_and_resume{}, false) {} +} + +task g() { + switch (co_await suspend_and_resume{}, 0) { + default: break; + } +} + +int main() { + f(); + g(); +}