From patchwork Fri Aug 2 10:50:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Sandoe X-Patchwork-Id: 1968299 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=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=W+VLuoMl; 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 4Wb2h03rfPz1yZl for ; Fri, 2 Aug 2024 20:51:28 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9B9113857000 for ; Fri, 2 Aug 2024 10:51:26 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by sourceware.org (Postfix) with ESMTPS id 1B4263858D26 for ; Fri, 2 Aug 2024 10:51:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1B4263858D26 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1B4263858D26 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::434 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722595863; cv=none; b=KMgybJ1YhCOup4cko7g+SsEAcoVhEBlH5B4h34zldZph/bAHoD0XRDd7iUcTW0K4uLLZr/grl0z7go4ujuY2NvtXSmfeOLPHVnnq+IZVMdSKJYC9SE533BS/LSA+MUjyIj8AwjLi1q4X+j7Wu7kkLiX/TsOJ1RzrjbX3sWN8M2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722595863; c=relaxed/simple; bh=JCiTpDE0y+YEztYX5dE26Fk2/sNMcVncD+q6EIBDJR4=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=iG7ip1n99QVzI9UZdkPzLx98VtEAHgopnWZrzBFYwdIfTlOwpcgzrTLeOE9w4lPvcOuwLf9x1s8MLxU+VkDIK/9vJucoLlC93r7QaVVL58Hoo+4xeBKPz5oVXe3IkF/g44r66oHOa2tXwIkQWPPWjUbqb/X0rnO//INZlYVeM4Y= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-wr1-x434.google.com with SMTP id ffacd0b85a97d-369cb9f086aso4385084f8f.0 for ; Fri, 02 Aug 2024 03:51:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1722595859; x=1723200659; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:reply-to:message-id:date :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=ChPauTCnw4/RzDLl6SXUPqb6SnqKqpKv1ERfBxvm/Vo=; b=W+VLuoMld4Xu0o/w/TwND7yzxXdSmRl3/xnTFU9PqVbhp9fL7C0Xo5+RWTNs1Agh++ kGQ79DY0dKkmRDLa5m3C2X/e2POZJLhHOWgaFFH1GT82wijTJWqNPAdEYiZL8i999u+Z G+pV6nEuplhxilu/l+uxhEF/hq9p/YI3ogXOYrtsNHdR5U3E6XEbojHi+6oEFg7GC4Wi u+Scb3+zaCj9rdn872no4Kv7VQGCPwPdDZTWAnaXpVnrM28lGog3+dqRnqs+ITY5KZE8 KZxT/ZOZeQco4eQor31zgpL7EbIuswQRNuiCICTfutIYuPlBcD9wOWONwklNFio8HcL/ duow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722595859; x=1723200659; h=content-transfer-encoding:mime-version:reply-to:message-id:date :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=ChPauTCnw4/RzDLl6SXUPqb6SnqKqpKv1ERfBxvm/Vo=; b=u2ivYT69jWco/kwzyDWDXt0X5eu38udo46qRXYdZknvesiOgtZfdlRbozA4bgdlFPG mmnIlYHarNLgtUQsthco58ERJ2sZd3EVVd9/HPVd5jI7QBxRQvcWUgwX7F/omKnnJozD uSNk3jdv25BMeG1nbzY6MNARxP+mtED03PCgCvsvGpW+L51Z48fz4Rafi1HhG/G+XHUy V7URQVymb3sBZuK05zkTZLEkJP2g8eLDiP3Z2bOAR7es4G0V7aplQv+Vec3h/pInQAVv ei1MCi/LlqUtYkWde1ceLyr5fa8yTBulih0ErP/nMbowmzNttnMuW5GtM3v/C1S7I70Z aIGQ== X-Gm-Message-State: AOJu0YzxTIqjsdvr53etqaZcTQYOlp5GC/lkKmkW925PMTYCJKipXp4C 6v7T5xIJIHYaw6unOzVKhI83CPG9PrrgZKj2e+jsglRxQb2zKOmILVNLYXRb X-Google-Smtp-Source: AGHT+IFC7gzPXWJscBrshmcCg5qCRd2ykQso0Nio1U+fvM8awdgMDKXsuSIf1mBiAwEHm6tv+TwOfQ== X-Received: by 2002:adf:e903:0:b0:367:9ce3:1667 with SMTP id ffacd0b85a97d-36bbc10f362mr2109720f8f.15.1722595858940; Fri, 02 Aug 2024 03:50:58 -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 ffacd0b85a97d-36bbd02200asm1668869f8f.54.2024.08.02.03.50.58 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Fri, 02 Aug 2024 03:50:58 -0700 (PDT) From: Iain Sandoe X-Google-Original-From: Iain Sandoe To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com Subject: [PATCH] c++, coroutines: Simplify separation of the user function body and ramp. Date: Fri, 2 Aug 2024 11:50:57 +0100 Message-Id: <20240802105057.41134-1-iain@sandoe.co.uk> X-Mailer: git-send-email 2.39.2 (Apple Git-143) MIME-Version: 1.0 X-Spam-Status: No, score=-8.4 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.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: , Reply-To: iain@sandoe.co.uk Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org This fixes a (so far unreported) bug where we would handle noexcept ramps correctly, but omit exception specs - take this opportunity to simplify. Tested on x86_64-darwin, OK for trunk? thanks Iain --- 8< --- We need to separate the original user-authored function body from the definition of the ramp function (which is what is called instead). The function body tree is either in DECL_SAVED_TREE or the first operand of current_eh_spec_block (for functions with an EH spec). This version simplifies the process by extrating the second case directly instead of inspecting the DECL_SAVED_TREE trees to discover it. gcc/cp/ChangeLog: * coroutines.cc (use_eh_spec_block): New. (split_coroutine_body_from_ramp): New. (morph_fn_to_coro): Use split_coroutine_body_from_ramp(). Signed-off-by: Iain Sandoe --- gcc/cp/coroutines.cc | 97 ++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index af03f5e0f74..fc80a4ec24c 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -4437,6 +4437,50 @@ coro_rewrite_function_body (location_t fn_start, tree fnbody, tree orig, return update_body; } +static bool +use_eh_spec_block (tree fn) +{ + return (flag_exceptions && flag_enforce_eh_specs + && !type_throw_all_p (TREE_TYPE (fn))); +} + +/* Extract the body of the function we are going to outline, leaving + to original function decl ready to build the ramp. */ + +static tree +split_coroutine_body_from_ramp (tree fndecl, tree eh_spec_block) +{ + tree body; + /* Once we've tied off the original user-authored body in fn_body. + Start the replacement synthesized ramp body. */ + + if (use_eh_spec_block (fndecl)) + { + body = pop_stmt_list (TREE_OPERAND (eh_spec_block, 0)); + TREE_OPERAND (eh_spec_block, 0) = push_stmt_list (); + } + else + { + body = pop_stmt_list (DECL_SAVED_TREE (fndecl)); + DECL_SAVED_TREE (fndecl) = push_stmt_list (); + } + + /* We can't validly get here with an empty statement list, since there's no + way for the FE to decide it's a coroutine in the absence of any code. */ + gcc_checking_assert (body != NULL_TREE); + + /* If we have an empty or erroneous function body, do not try to transform it + since that would potentially wrap errors. */ + tree body_start = expr_first (body); + if (body_start == NULL_TREE || body_start == error_mark_node) + { + /* Restore the original state. */ + add_stmt (body); + return NULL_TREE; + } + return body; +} + /* Here we: a) Check that the function and promise type are valid for a coroutine. @@ -4483,57 +4527,22 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) /* Discard the body, we can't process it further. */ pop_stmt_list (DECL_SAVED_TREE (orig)); DECL_SAVED_TREE (orig) = push_stmt_list (); + /* Match the expected nesting when an eh block is in use. */ + if (use_eh_spec_block (orig)) + current_eh_spec_block = begin_eh_spec_block (); return false; } - /* We can't validly get here with an empty statement list, since there's no - way for the FE to decide it's a coroutine in the absence of any code. */ - tree fnbody = pop_stmt_list (DECL_SAVED_TREE (orig)); - gcc_checking_assert (fnbody != NULL_TREE); - /* We don't have the locus of the opening brace - it's filled in later (and there doesn't really seem to be any easy way to get at it). The closing brace is assumed to be input_location. */ location_t fn_start = DECL_SOURCE_LOCATION (orig); - gcc_rich_location fn_start_loc (fn_start); - - /* Initial processing of the function-body. - If we have no expressions or just an error then punt. */ - tree body_start = expr_first (fnbody); - if (body_start == NULL_TREE || body_start == error_mark_node) - { - DECL_SAVED_TREE (orig) = push_stmt_list (); - append_to_statement_list (fnbody, &DECL_SAVED_TREE (orig)); - /* Suppress warnings about the missing return value. */ - suppress_warning (orig, OPT_Wreturn_type); - return false; - } - - /* So, we've tied off the original user-authored body in fn_body. - - Start the replacement synthesized ramp body as newbody. - If we encounter a fatal error we might return a now-empty body. - Note, the returned ramp body is not 'popped', to be compatible with - the way that decl.cc handles regular functions, the scope pop is done - in the caller. */ - - tree newbody = push_stmt_list (); - DECL_SAVED_TREE (orig) = newbody; - - /* If our original body is noexcept, then that's what we apply to our - generated ramp, transfer any MUST_NOT_THOW_EXPR to that. */ - bool is_noexcept = TREE_CODE (body_start) == MUST_NOT_THROW_EXPR; - if (is_noexcept) - { - /* The function body we will continue with is the single operand to - the must-not-throw. */ - fnbody = TREE_OPERAND (body_start, 0); - /* Transfer the must-not-throw to the ramp body. */ - add_stmt (body_start); - /* Re-start the ramp as must-not-throw. */ - TREE_OPERAND (body_start, 0) = push_stmt_list (); - } + /* FIXME: This has the hidden side-effect of preparing the current function + to be the ramp. */ + tree fnbody = split_coroutine_body_from_ramp (orig, current_eh_spec_block); + if (!fnbody) + return false; /* If the original function has a return value with a non-trivial DTOR and the body contains a var with a DTOR that might throw, the decl is @@ -5059,7 +5068,6 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) if (get_ro == error_mark_node) { BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body); - DECL_SAVED_TREE (orig) = newbody; /* Suppress warnings about the missing return value. */ suppress_warning (orig, OPT_Wreturn_type); return false; @@ -5286,7 +5294,6 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) pop_deferring_access_checks (); - DECL_SAVED_TREE (orig) = newbody; /* Link our new functions into the list. */ TREE_CHAIN (destroy) = TREE_CHAIN (orig); TREE_CHAIN (actor) = destroy;