From patchwork Mon Sep 27 19:38:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Sandoe X-Patchwork-Id: 45483 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 96F363858439 for ; Mon, 27 Sep 2021 19:39:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 96F363858439 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1632771558; bh=/V9rdglhW2mCiHfVbV81bOmHIjGK1rOLjLRbOHFPabA=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=PB9UdcWnEK8iGN3+xduZ9mRKf0PSgWkBUCqUqs2SmYRx70sNPntDHjGHUWMFcDTMO USKL0X2Hur5Ae97I6ycD+KaTcyZMJVDg60EdEBOu1u9OeDoEz3KHC1Ha0qU+sPcYs5 H/Ucv6WUqWl1yArOxl7G+VHeVJPgbPt6ZI++pyVU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by sourceware.org (Postfix) with ESMTPS id E05DA3858022 for ; Mon, 27 Sep 2021 19:38:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E05DA3858022 Received: by mail-wm1-x332.google.com with SMTP id z2so1435591wmc.3 for ; Mon, 27 Sep 2021 12:38:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :mime-version:content-transfer-encoding; bh=/V9rdglhW2mCiHfVbV81bOmHIjGK1rOLjLRbOHFPabA=; b=Xf/xLbYPao9s+WNfL4+bXTE5AYVXgoRoVID3/U9FaByv2VLCpdM/IWcQa6xVgzExL2 9EqcPamh0VplTOTdc459TRowQVVSqKAqW1bowI4NOyPl/ZsxxOWAdqAazjT3NK9AKGQq SDKS4McToyQA/+BiyI4MvRsi5MKJSemXVGKWdaT+v9IQkigf9jd3O7Dy5AFAeNI+5GRb fu+jNjpZ3jd8Ubj6pfwc/vrOqptJZMu3r4ZpYukdzJNJOAXaEVSgjc1XpxvdHoyl7t2j V5Kv3xo7n7B+q157wLX3Z+xmF8bj5pjkeIzVIim+eHi4lDOc/ckzo2+HqvGnqvnWYQpv UpMg== X-Gm-Message-State: AOAM530M4LyKwI2zvcSpF7Gq0rBzZwH57D1o7aN67nk5f8LORMh66Yir b6eOZHwYwXC/HkGlAR1QFqT0tLJeaWgDQw== X-Google-Smtp-Source: ABdhPJwOJD7dmjd9Afjysb81MW4VEXvLgj1YeoDnAmdFwr4P16IPcwAE6Z4sCNPz2giKmsS0PPrKHQ== X-Received: by 2002:a05:600c:b41:: with SMTP id k1mr890636wmr.4.1632771513921; Mon, 27 Sep 2021 12:38:33 -0700 (PDT) Received: from localhost.localdomain (host81-138-1-83.in-addr.btopenworld.com. [81.138.1.83]) by smtp.gmail.com with ESMTPSA id o5sm6215546wrf.85.2021.09.27.12.38.33 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Sep 2021 12:38:33 -0700 (PDT) X-Google-Original-From: Iain Sandoe To: gcc-patches@gcc.gnu.org Subject: [PATCH] coroutines: Only set parm copy guard vars if we have exceptions [PR 102454]. Date: Mon, 27 Sep 2021 20:38:27 +0100 Message-Id: <20210927193827.4514-1-iain@sandoe.co.uk> X-Mailer: git-send-email 2.24.3 (Apple Git-128) MIME-Version: 1.0 X-Spam-Status: No, score=-8.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Iain Sandoe via Gcc-patches From: Iain Sandoe Reply-To: iain@sandoe.co.uk Cc: Iain Sandoe Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" For coroutines, we make copies of the original function arguments into the coroutine frame. Normally, these are destroyed on the proper exit from the coroutine when the frame is destroyed. However, if an exception is thrown before the first suspend point is reached, the cleanup has to happen in the ramp function. These cleanups are guarded such that they are only applied to any param copies actually made. The ICE is caused by an attempt to set the guard variable when there are no exceptions enabled (the guard var is not created in this case). Fixed by checking for flag_exceptions in this case too. While touching this code paths, also clean up the synthetic names used when a function parm is unnamed. tested on x86_64-darwin, OK for master? thanks Iain Signed-off-by: Iain Sandoe PR c++/102454 gcc/cp/ChangeLog: * coroutines.cc (analyze_fn_parms): Clean up synthetic names for unnamed function params. (morph_fn_to_coro): Do not try to set a guard variable for param DTORs in the ramp, unless we have exceptions active. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr102454.C: New test. --- gcc/cp/coroutines.cc | 26 ++++++++------- gcc/testsuite/g++.dg/coroutines/pr102454.C | 38 ++++++++++++++++++++++ 2 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/coroutines/pr102454.C diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index fbd5c49533f..c761e769c12 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -3829,13 +3829,12 @@ analyze_fn_parms (tree orig) if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (parm.frame_type)) { - char *buf = xasprintf ("_Coro_%s_live", IDENTIFIER_POINTER (name)); - parm.guard_var = build_lang_decl (VAR_DECL, get_identifier (buf), - boolean_type_node); - free (buf); - DECL_ARTIFICIAL (parm.guard_var) = true; - DECL_CONTEXT (parm.guard_var) = orig; - DECL_INITIAL (parm.guard_var) = boolean_false_node; + char *buf = xasprintf ("%s%s_live", DECL_NAME (arg) ? "_Coro_" : "", + IDENTIFIER_POINTER (name)); + parm.guard_var + = coro_build_artificial_var (UNKNOWN_LOCATION, get_identifier (buf), + boolean_type_node, orig, + boolean_false_node); parm.trivial_dtor = false; } else @@ -4843,11 +4842,14 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) NULL, parm.frame_type, LOOKUP_NORMAL, tf_warning_or_error); - /* This var is now live. */ - r = build_modify_expr (fn_start, parm.guard_var, - boolean_type_node, INIT_EXPR, fn_start, - boolean_true_node, boolean_type_node); - finish_expr_stmt (r); + if (flag_exceptions) + { + /* This var is now live. */ + r = build_modify_expr (fn_start, parm.guard_var, + boolean_type_node, INIT_EXPR, fn_start, + boolean_true_node, boolean_type_node); + finish_expr_stmt (r); + } } } } diff --git a/gcc/testsuite/g++.dg/coroutines/pr102454.C b/gcc/testsuite/g++.dg/coroutines/pr102454.C new file mode 100644 index 00000000000..41aeda7b973 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr102454.C @@ -0,0 +1,38 @@ +// { dg-additional-options "-fno-exceptions" } + +#include +#include + +template +struct looper { + struct promise_type { + auto get_return_object () { return handle_type::from_promise (*this); } + auto initial_suspend () { return suspend_always_prt {}; } + auto final_suspend () noexcept { return suspend_always_prt {}; } + void return_value (T); + void unhandled_exception (); + }; + + using handle_type = std::coroutine_handle; + + looper (handle_type); + + struct suspend_always_prt { + bool await_ready () noexcept; + void await_suspend (handle_type) noexcept; + void await_resume () noexcept; + }; +}; + +template +looper +with_ctorable_state (T) +{ + co_return T (); +} + +auto +foo () +{ + return with_ctorable_state; +}