From patchwork Thu Apr 30 12:53:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Iain Sandoe X-Patchwork-Id: 1280344 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sandoe.co.uk Received: from 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 RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49Cb0l26r7z9sSg for ; Thu, 30 Apr 2020 22:53:41 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DE9CC395CCBD; Thu, 30 Apr 2020 12:53:39 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp1.wavenetuk.net (smtp.wavenetuk.net [195.26.36.10]) by sourceware.org (Postfix) with ESMTP id A1687395CC81 for ; Thu, 30 Apr 2020 12:53:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A1687395CC81 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=sandoe.co.uk Authentication-Results: sourceware.org; spf=none smtp.mailfrom=iain@sandoe.co.uk Received: from [192.168.1.212] (host81-138-1-83.in-addr.btopenworld.com [81.138.1.83]) by smtp1.wavenetuk.net (Postfix) with ESMTPA id EAAD11200A6D; Thu, 30 Apr 2020 13:53:35 +0100 (BST) From: Iain Sandoe Mime-Version: 1.0 (Mac OS X Mail 10.3 \(3273\)) Subject: [PATCH] coroutines: Fix handling of target cleanup exprs [PR94883] Message-Id: <7446DE66-1B94-4EA3-A524-49B49758E80E@sandoe.co.uk> Date: Thu, 30 Apr 2020 13:53:25 +0100 To: GCC Patches X-Mailer: Apple Mail (2.3273) X-Spam-Status: No, score=-25.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_COUK, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KHOP_HELO_FCRDNS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: , Cc: Nathan Sidwell Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi Another case found building folly’s experimental coros tests. tested on x86_64-darwin, linux, powerpc64-linux OK for master? thanks Iain ---- The problem here is that target cleanup expressions have been added to the initialisers for the awaitable (and returns of non-trivial values from await_suspend() calls). This is because the expansion of the co_await into its control flow is not apparent to the machinery adding the target cleanup expressions. The solution being tested is simply to recreate target expressions as the co_awaits are lowered. Teaching the machinery to handle walking co_await expressions in different ways at different points (outside the coroutine transformation) seems overly complex. gcc/cp/ChangeLog: 2020-04-30 Iain Sandoe PR c++/94883 * coroutines.cc (register_awaits): Update target expressions for awaitable and suspend handle initializers. gcc/testsuite/ChangeLog: 2020-04-30 Iain Sandoe PR c++/94883 * g++.dg/coroutines/pr94883-folly-2.C: New test. --- gcc/cp/coroutines.cc | 11 ++++ .../g++.dg/coroutines/pr948xx-folly-2.C | 64 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 gcc/testsuite/g++.dg/coroutines/pr948xx-folly-2.C diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 7bb3e98fe6c..3bff2c7dbdc 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -2754,6 +2754,17 @@ register_awaits (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d) free (nam); } + tree o = TREE_OPERAND (aw_expr, 2); /* Initialiser for the frame var. */ + /* If this is a target expression, then we need to remake it to strip off + any extra cleanups added. */ + if (TREE_CODE (o) == TARGET_EXPR) + TREE_OPERAND (aw_expr, 2) = get_target_expr (TREE_OPERAND (o, 1)); + + tree v = TREE_OPERAND (aw_expr, 3); + o = TREE_VEC_ELT (v, 1); + if (TREE_CODE (o) == TARGET_EXPR) + TREE_VEC_ELT (v, 1) = get_target_expr (TREE_OPERAND (o, 1)); + register_await_info (aw_expr, aw_field_type, aw_field_nam); /* Count how many awaits the current expression contains. */ diff --git a/gcc/testsuite/g++.dg/coroutines/pr948xx-folly-2.C b/gcc/testsuite/g++.dg/coroutines/pr948xx-folly-2.C new file mode 100644 index 00000000000..088f1335493 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr948xx-folly-2.C @@ -0,0 +1,64 @@ + +namespace std { +template struct coroutine_traits : a {}; +template struct coroutine_handle; +template <> struct coroutine_handle<> {}; +template struct coroutine_handle : coroutine_handle<> {}; +struct b { + bool await_ready(); + void await_suspend(coroutine_handle<>); + void await_resume(); +}; +} // namespace std + +template auto ab(int ac, d ad) -> decltype(ad.e(ac)); +int f; +class h { + class j { + public: + bool await_ready(); + void await_suspend(std::coroutine_handle<>); + void await_resume(); + }; + +public: + void get_return_object(); + std::b initial_suspend(); + j final_suspend(); + void unhandled_exception(); + template + auto await_transform (g c) { return ab(f, c); } +}; +template class k { +public: + using promise_type = h; + using i = std::coroutine_handle<>; + class l { + public: + ~l(); + operator bool(); + }; + class m { + public: + bool await_ready(); + i await_suspend(std::coroutine_handle<>); + l await_resume(); + }; + class n { + public: + m e(int); + }; + n ah(); +}; + +template +k +my_coro (k am, ai) { + if (auto an = co_await am.ah()) + ; +} + +void foo () { + k a; + my_coro (a, [] {}); +}