From patchwork Tue Jul 23 23:41:49 2024 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: 1964100 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aarsen.me header.i=@aarsen.me header.a=rsa-sha256 header.s=MBO0001 header.b=R+jjgSb8; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTGNq3dQxz1yXx for ; Wed, 24 Jul 2024 11:18:19 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9D970385843B for ; Wed, 24 Jul 2024 01:18:17 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-101.mailbox.org (mout-p-101.mailbox.org [80.241.56.151]) by sourceware.org (Postfix) with ESMTPS id A9E3E3858D29 for ; Wed, 24 Jul 2024 01:17:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A9E3E3858D29 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=aarsen.me Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=aarsen.me ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A9E3E3858D29 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=80.241.56.151 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721783869; cv=none; b=xI3JNY4dyesMt6a9aSZPhXvQ97UHm1qfPX5HHA1lbvhmJG+inlqQXp7YZ4BtDdxanT3tvHPIR3Id8gIOq8mX3MciJUxZeGMZ9viEV/CamVphdG9nLBToRqPL5jN66GWsPKNpqrldbVblujVuKZPqqyuVXtBYjlkYQeneim9EcWI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721783869; c=relaxed/simple; bh=bbLAhQQ9VlkCDMTR68v6lTdh23ZFGcFn7GNIrjY5E/8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=JGSB2oQA1eiLVzmGhMWVAScacM1hjJjxwqNmJWHuA97idg7Psjs5fUEWe1OkVb74iKmt7ty/5C5IeU2fn+TaqXanKN74FN3s3SJGv76YG39lStl3QH0CKV1ASYskdntplrFn8rrH0EW5FZf3vpI7Rl7zXYcz1Fm4rCktueG4aDk= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smtp202.mailbox.org (smtp202.mailbox.org [IPv6:2001:67c:2050:b231:465::202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4WTGN834mbz9slB; Wed, 24 Jul 2024 03:17:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1721783864; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=am/I9w3Z3n2/IvavOdxS7ncthTHTZTSKU++KdFT8ZdU=; b=R+jjgSb8H9Iy7dgHnxTSMmgsZa9zl2kx7c9qFQG3Py+oz9CXXQlo9640+QBvz5ht39QXun ZVijhk1AJFs+Dx3HFy0nMs/wpEMNxx5okJW+8Ah8MIL1Y2y5gnBiRJzrCaY9gFtX08/Ypp Ac3tjMZQy576Nw6M7C15L2Y3z7VuxWg532MkeddeS4DuLuictyGqGQtrgZX228Y4FfjGYI pOmvzIJd/eAMavaKL6VXYMiJC74B9mthQQ/b5jtgdtWIAh0+JHgxhsP3uItFKCUSyk4OwA 3MeW9IBo9C3/SIJQCTTn4atPK+Dr+8waYUUt4Jv2o/cOs84vmR1pl0xP/CA1zA== From: =?utf-8?q?Arsen_Arsenovi=C4=87?= To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, iain@sandoe.co.uk, =?utf-8?q?Arsen_Arsenovi=C4=87?= Subject: [PATCH 1/2] cp/coroutines: do not rewrite parameters in unevaluated contexts Date: Wed, 24 Jul 2024 01:41:49 +0200 Message-ID: <20240724011619.2013098-1-arsen@aarsen.me> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4WTGN834mbz9slB X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_INFOUSMEBIZ, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org It is possible to use parameters of a parent function of a lambda in unevaluated contexts without capturing them. By not capturing them, we work around the usual mechanism we use to prevent rewriting captured parameters. Prevent this by simply skipping rewrites in unevaluated contexts. Those won't mind the value not being present anyway. gcc/cp/ChangeLog: PR c++/111728 * coroutines.cc (rewrite_param_uses): Skip unevaluated subexpressions. gcc/testsuite/ChangeLog: PR c++/111728 * g++.dg/coroutines/pr111728.C: New test. --- Evening! This 'series' contains two patches for the coroutine implementation to address two unrelated PRs. The first prevents an ICE during coroutine parameter substitution by not performing it in unevaluated contexts. Those contexts can contain names that were not captured by lambdas but *are* parameters to coroutines. In the testcase from the PR, the rewriting machinery finds a param in the body of the coroutine, which it did not previously encounter while processing the coroutine declaration, and that does not have a DECL_VALUE_EXPR, and fails. Since it is not really useful to rewrite parameter uses in unevaluated contexts, we can just ignore those, preventing confusion (and the ICE). Regression tested on x86_64-pc-linux-gnu. OK for trunk? TIA, have a lovely night. gcc/cp/coroutines.cc | 6 +++++ gcc/testsuite/g++.dg/coroutines/pr111728.C | 29 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 gcc/testsuite/g++.dg/coroutines/pr111728.C diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index e8f028df3ad..fb8f24e6c61 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -3755,6 +3755,12 @@ rewrite_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d) return cp_walk_tree (&t, rewrite_param_uses, d, NULL); } + if (unevaluated_p (TREE_CODE (*stmt))) + { + *do_subtree = 0; // Nothing to do. + return NULL_TREE; + } + if (TREE_CODE (*stmt) != PARM_DECL) return NULL_TREE; diff --git a/gcc/testsuite/g++.dg/coroutines/pr111728.C b/gcc/testsuite/g++.dg/coroutines/pr111728.C new file mode 100644 index 00000000000..c1fee4b36a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr111728.C @@ -0,0 +1,29 @@ +// { dg-do compile } +// https://gcc.gnu.org/PR111728 +#include +struct promise; +struct coroutine : std::coroutine_handle +{ + using promise_type = ::promise; + bool await_ready() { return false; } + void await_suspend(coroutine_handle h) {} + int await_resume() { return {} ;} +}; +struct promise +{ + coroutine get_return_object() { return {coroutine::from_promise(*this)}; } + std::suspend_always initial_suspend() noexcept { return {}; } + std::suspend_always final_suspend() noexcept { return {}; } + void return_void() {} + void unhandled_exception() {} +}; +coroutine +write_fields() { + int static_buffer[10]; + co_await [](auto) + -> coroutine + { + if (sizeof(static_buffer)); + co_return; + }(0); +} From patchwork Tue Jul 23 23:41:50 2024 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: 1964101 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aarsen.me header.i=@aarsen.me header.a=rsa-sha256 header.s=MBO0001 header.b=KHiyLwrN; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTGNr5q4Kz1yXx for ; Wed, 24 Jul 2024 11:18:20 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id ECB053858C98 for ; Wed, 24 Jul 2024 01:18:18 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-102.mailbox.org (mout-p-102.mailbox.org [IPv6:2001:67c:2050:0:465::102]) by sourceware.org (Postfix) with ESMTPS id 9B3CF3858D34 for ; Wed, 24 Jul 2024 01:17:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9B3CF3858D34 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=aarsen.me Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=aarsen.me ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9B3CF3858D34 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2001:67c:2050:0:465::102 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721783870; cv=none; b=LmOP4XhQ3K+fgoECHlrstdLhH/8rwVB1DG999NF5eTulajgdHoy8Zx6EVwAp9G2Lim+Nai/zYyShig41SxUYl1P4FHg+y7RhlH6uWJWSPn/zrlrWfLH8kVeuvvvPQRcxxqc0BRAZ05Goiq16Ls48XZeVeHKpVGUyIk6mMqfxdIg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721783870; c=relaxed/simple; bh=CiKK2o3KNe3vKgnTrlUgE+mMyyl72uF1ETKJ/cEktTI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=JhMhs4ptc3ekXLgrBCZvhEHWox2v06uLhNahFIE6foZRc1bTxFC9ltpASm2bwMqfAJ84m2q8pzVhRA8pRy6YXnCe50XcqOLXiUWP978j/20I2K5BEYnoap0Oxk+0Cs+QXrVKF60YcDACseNomBsNT0YVjcIaXTsmp4nBXChbA94= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smtp202.mailbox.org (smtp202.mailbox.org [IPv6:2001:67c:2050:b231:465::202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-102.mailbox.org (Postfix) with ESMTPS id 4WTGN95C1kz9skx; Wed, 24 Jul 2024 03:17:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1721783865; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nfK5G2rqnpiSJqwsrar5wq+rTBOQKFYhAMhC8hl4NiE=; b=KHiyLwrN+Qew9/FzkHwOgWgC80rvngB74PsOcIytfKnplmJpp3f5zGJ1516hnpyY37ITgu 43WDYh4cQu2qxVpdzoGMZkybW6soa/lJe5YeGUmc1aWpH84ADwWpBeAqF/D60SffGQqqEx YDLthU2zVqv9VpW/J3T+Onklp5vWwhPfp5uq0VOz/UVI0cpwSWYsKxfG1LhQ1HEF//hEoD MGieAU8y+82mp7015wKT1u7/faZ1u/kGL9IY313UBFLDpnqX6EOvW3xaKQXrOxtzOXQl9E KI9tbJ6Dg3LZq/fHoFPWDmZSFZowZ/qGfuLTYXq3kzAIXE2mmS04hhKQhQN/Kg== From: =?utf-8?q?Arsen_Arsenovi=C4=87?= To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, iain@sandoe.co.uk, =?utf-8?q?Arsen_Arsenovi=C4=87?= Subject: [PATCH 2/2] cp+coroutines: teach convert_to_void to diagnose discarded co_awaits Date: Wed, 24 Jul 2024 01:41:50 +0200 Message-ID: <20240724011619.2013098-2-arsen@aarsen.me> In-Reply-To: <20240724011619.2013098-1-arsen@aarsen.me> References: <20240724011619.2013098-1-arsen@aarsen.me> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4WTGN95C1kz9skx X-Spam-Status: No, score=-10.9 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org co_await expressions are nearly calls to Awaitable::await_resume, and, as such, should inherit its nodiscard. A discarded co_await expression should, hence, act as if its call to await_resume was discarded. CO_AWAIT_EXPR trees do conveniently contain the expression for calling await_resume in them, so we can discard it. gcc/cp/ChangeLog: PR c++/110171 * coroutines.cc (co_await_get_resume_call): New function. Returns the await_resume expression of a given co_await. * cp-tree.h (co_await_get_resume_call): New function. * cvt.cc (convert_to_void): Handle CO_AWAIT_EXPRs and call maybe_warn_nodiscard on their resume exprs. gcc/testsuite/ChangeLog: PR c++/110171 * g++.dg/coroutines/pr110171-1.C: New test. * g++.dg/coroutines/pr110171.C: New test. --- This patch teaches convert_to_void how to discard 'through' a CO_AWAIT_EXPR. CO_AWAIT_EXPR nodes (most of the time) already contain their relevant await_resume() call embedded within them, so, when we discard a CO_AWAIT_EXPR, we can also just discard the await_resume() call embedded within it. This results in a [[nodiscard]] diagnostic that the PR noted was missing. As with the previous patch, regression-tested on x86_64-pc-linux-gnu. OK for trunk? TIA. gcc/cp/coroutines.cc | 13 ++++++++ gcc/cp/cp-tree.h | 3 ++ gcc/cp/cvt.cc | 8 +++++ gcc/testsuite/g++.dg/coroutines/pr110171-1.C | 34 ++++++++++++++++++++ gcc/testsuite/g++.dg/coroutines/pr110171.C | 32 ++++++++++++++++++ 5 files changed, 90 insertions(+) create mode 100644 gcc/testsuite/g++.dg/coroutines/pr110171-1.C create mode 100644 gcc/testsuite/g++.dg/coroutines/pr110171.C diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index fb8f24e6c61..05486c2fb19 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -596,6 +596,19 @@ coro_get_destroy_function (tree decl) return NULL_TREE; } +/* Given a CO_AWAIT_EXPR AWAIT_EXPR, return its resume call. */ + +tree* +co_await_get_resume_call (tree await_expr) +{ + gcc_checking_assert (TREE_CODE (await_expr) == CO_AWAIT_EXPR); + tree vec = TREE_OPERAND (await_expr, 3); + if (!vec) + return nullptr; + return &TREE_VEC_ELT (vec, 2); +} + + /* These functions assumes that the caller has verified that the state for the decl has been initialized, we try to minimize work here. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 856699de82f..c9ae8950bd1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8763,6 +8763,9 @@ extern tree coro_get_actor_function (tree); extern tree coro_get_destroy_function (tree); extern tree coro_get_ramp_function (tree); +extern tree* co_await_get_resume_call (tree await_expr); + + /* contracts.cc */ extern tree make_postcondition_variable (cp_expr); extern tree make_postcondition_variable (cp_expr, tree); diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc index d95e01c118c..7b4bd8a9dc4 100644 --- a/gcc/cp/cvt.cc +++ b/gcc/cp/cvt.cc @@ -1502,6 +1502,14 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) maybe_warn_nodiscard (expr, implicit); break; + case CO_AWAIT_EXPR: + { + auto awr = co_await_get_resume_call (expr); + if (awr && *awr) + *awr = convert_to_void (*awr, implicit, complain); + break; + } + default:; } expr = resolve_nondeduced_context (expr, complain); diff --git a/gcc/testsuite/g++.dg/coroutines/pr110171-1.C b/gcc/testsuite/g++.dg/coroutines/pr110171-1.C new file mode 100644 index 00000000000..d8aff582487 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr110171-1.C @@ -0,0 +1,34 @@ +// { dg-do compile } +#include + +struct must_check_result +{ + bool await_ready() { return false; } + void await_suspend(std::coroutine_handle<>) {} + [[nodiscard]] bool await_resume() { return {}; } +}; + +struct task {}; + +namespace std +{ + template + struct coroutine_traits + { + struct promise_type + { + task get_return_object() { return {}; } + suspend_always initial_suspend() noexcept { return {}; } + suspend_always final_suspend() noexcept { return {}; } + void return_void() {} + void unhandled_exception() {} + }; + }; +} + +task example(auto) +{ + co_await must_check_result(); // { dg-warning "-Wunused-result" } +} + +void f() { example(1); } diff --git a/gcc/testsuite/g++.dg/coroutines/pr110171.C b/gcc/testsuite/g++.dg/coroutines/pr110171.C new file mode 100644 index 00000000000..4b82e23656c --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr110171.C @@ -0,0 +1,32 @@ +// { dg-do compile } +#include + +struct must_check_result +{ + bool await_ready() { return false; } + void await_suspend(std::coroutine_handle<>) {} + [[nodiscard]] bool await_resume() { return {}; } +}; + +struct task {}; + +namespace std +{ + template + struct coroutine_traits + { + struct promise_type + { + task get_return_object() { return {}; } + suspend_always initial_suspend() noexcept { return {}; } + suspend_always final_suspend() noexcept { return {}; } + void return_void() {} + void unhandled_exception() {} + }; + }; +} + +task example() +{ + co_await must_check_result(); // { dg-warning "-Wunused-result" } +}