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" } +}