From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id CD08C3858D1E for ; Mon, 19 Dec 2022 15:54:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CD08C3858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1671465264; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LeWQhY61jDiZe/RhcCeKAp6xbExLfJ4wkK6TqS7jePU=; b=YltRv4Poikbi80aBN7kKQwUlvFlEDGmZ1pd93CcR6qCSHtE6kfmAq8ExqpFYbXznlAZwzk uVcexj87V0JDCN+12XjFi8QrOH8gRmsEsKdRHgjj/5gA7fsJMnQYFI/1xGG5AhKyIvAgDL nuPCk9hVSzdFYUZ9RnI/BVskt0/ERt0= Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-142-nnXAR0-5M8C3wGhlqUM3ig-1; Mon, 19 Dec 2022 10:54:23 -0500 X-MC-Unique: nnXAR0-5M8C3wGhlqUM3ig-1 Received: by mail-qk1-f199.google.com with SMTP id br6-20020a05620a460600b007021e1a5c48so7488686qkb.6 for ; Mon, 19 Dec 2022 07:54:23 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:references:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=LeWQhY61jDiZe/RhcCeKAp6xbExLfJ4wkK6TqS7jePU=; b=RTT8sGXtopYhrbCdrH54VoZWxePfGWarX6inIUZdOZEu4iKwtOB94XVOfz/LlBxJPZ /1DApQ4WWIEqJpe3zFNzzm98y4yAV6oJAaYlG5ubUSMC7MMqEnoioLV8Z6oWMt4Xbq26 tvQpM0KhhlflENgUSclsDhR5FFfXRrwOtkqCzekMDtwHU9E2ewNhQsIO12Fe5aj935N5 wgpBTk1s/TU/ZQzse0lg9r4IOa2WRvvDRE9KZgBBetR1s6UdSTUAcvrfJkxOha3/MfFP SXNFd+X0y8RK7agqAI8rIZ4DyK3O4f4TeyDOoiUmbdwn1zRlq8ev6V2g9MUa01zKAAHS AgBg== X-Gm-Message-State: AFqh2kpB7Xe48NyQhrVJf4zJcXoPb3odeBYq+YQgv0dCyOIboJe1stGy TcEl6wP3d+nP+ZU5t4eBWpYZW/kKaZIaRWf4Av7c3AiW9wx05jdgHXEvydQwymzTVDxgzcDqlIv VMIKZ71AIy5A95Yoxqg== X-Received: by 2002:ac8:7188:0:b0:3a8:30f8:bc13 with SMTP id w8-20020ac87188000000b003a830f8bc13mr12851071qto.44.1671465262764; Mon, 19 Dec 2022 07:54:22 -0800 (PST) X-Google-Smtp-Source: AMrXdXuud+AQqysej57w6r93q6wC31aZPtQuGKXIVv8Apmrhe/JsBK24D9AavkMsVYyRYxdcCxOOkA== X-Received: by 2002:ac8:7188:0:b0:3a8:30f8:bc13 with SMTP id w8-20020ac87188000000b003a830f8bc13mr12851041qto.44.1671465262403; Mon, 19 Dec 2022 07:54:22 -0800 (PST) Received: from [192.168.1.108] (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id br36-20020a05620a462400b006fed58fc1a3sm7326165qkb.119.2022.12.19.07.54.21 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 19 Dec 2022 07:54:21 -0800 (PST) Message-ID: Date: Mon, 19 Dec 2022 10:54:20 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.5.1 Subject: Re: [PATCH v2] coroutines: Accept 'extern "C"' coroutines. To: Iain Sandoe , GCC Patches References: <20221210113744.38708-1-iain@sandoe.co.uk> <0FD0D3D2-EB28-41DD-9F08-BD8BB267F238@sandoe.co.uk> From: Jason Merrill In-Reply-To: <0FD0D3D2-EB28-41DD-9F08-BD8BB267F238@sandoe.co.uk> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,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 List-Id: On 12/17/22 08:40, Iain Sandoe wrote: > Hi. > > It seems that everyone agrees that extern C coroutines should be permitted, > although I have yet to see a useful testcase. > > This patch has been revised to append the suffices for such functions in > mangle.cc rather than as part of the outlined function decl production. > > tested on x86_64-darwin21. > OK for trunk? > Iain OK, thanks. > > — 8< — > > 'extern "C"' coroutines are permitted by the standard and expected to work > (although constructing useful cases could be challenging). In order to > permit this we need to arrange for the outlined helper functions to be > named properly, even when no mangling is required. To do this, we append > the actor and destroy suffixes in all cases. > > Signed-off-by: Iain Sandoe > > gcc/cp/ChangeLog: > > * mangle.cc (write_mangled_name): Append the helper function > suffixes here... > (write_encoding): ... rather than here. > > gcc/testsuite/ChangeLog: > > * g++.dg/coroutines/torture/extern-c-coroutine.C: New test. > --- > gcc/cp/mangle.cc | 23 ++--- > .../coroutines/torture/extern-c-coroutine.C | 89 +++++++++++++++++++ > 2 files changed, 101 insertions(+), 11 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/coroutines/torture/extern-c-coroutine.C > > diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc > index 074cf27ec7a..5789adcf680 100644 > --- a/gcc/cp/mangle.cc > +++ b/gcc/cp/mangle.cc > @@ -805,6 +805,18 @@ write_mangled_name (const tree decl, bool top_level) > write_string (".pre"); > else if (DECL_IS_POST_FN_P (decl)) > write_string (".post"); > + > + /* If this is a coroutine helper, then append an appropriate string to > + identify which. */ > + if (tree ramp = DECL_RAMP_FN (decl)) > + { > + if (DECL_ACTOR_FN (ramp) == decl) > + write_string (JOIN_STR "actor"); > + else if (DECL_DESTROY_FN (ramp) == decl) > + write_string (JOIN_STR "destroy"); > + else > + gcc_unreachable (); > + } > } > > /* Returns true if the return type of DECL is part of its signature, and > @@ -863,17 +875,6 @@ write_encoding (const tree decl) > mangle_return_type_p (decl), > d); > > - /* If this is a coroutine helper, then append an appropriate string to > - identify which. */ > - if (tree ramp = DECL_RAMP_FN (decl)) > - { > - if (DECL_ACTOR_FN (ramp) == decl) > - write_string (JOIN_STR "actor"); > - else if (DECL_DESTROY_FN (ramp) == decl) > - write_string (JOIN_STR "destroy"); > - else > - gcc_unreachable (); > - } > } > } > > diff --git a/gcc/testsuite/g++.dg/coroutines/torture/extern-c-coroutine.C b/gcc/testsuite/g++.dg/coroutines/torture/extern-c-coroutine.C > new file mode 100644 > index 00000000000..c178a80ee4b > --- /dev/null > +++ b/gcc/testsuite/g++.dg/coroutines/torture/extern-c-coroutine.C > @@ -0,0 +1,89 @@ > +#include > +#include > + > +#ifndef OUTPUT > +# define PRINT(X) > +# define PRINTF(X,...) > +#else > +# define PRINT(X) puts(X) > +# define PRINTF printf > +#endif > + > +struct future { > + struct promise_type; > + using handle_type = std::coroutine_handle; > + handle_type handle; > + future () : handle(0) {} > + future (handle_type _handle) > + : handle(_handle) { > + PRINT("Created future object from handle"); > + } > + future (const future &) = delete; // no copying > + future (future &&s) : handle(s.handle) { > + s.handle = nullptr; > + PRINT("future mv ctor "); > + } > + future &operator = (future &&s) { > + handle = s.handle; > + s.handle = nullptr; > + PRINT("future op= "); > + return *this; > + } > + ~future() { > + PRINT("Destroyed future"); > + if ( handle ) > + handle.destroy(); > + } > + > + struct promise_type { > + void return_value (int v) { > + PRINTF ("return_value (%d)\n", v); > + vv = v; > + } > + > + std::suspend_always initial_suspend() noexcept { return {}; } > + std::suspend_always final_suspend() noexcept { return {}; } > + void unhandled_exception() {} > + auto get_return_object() {return handle_type::from_promise (*this);} > + > + int get_value () { return vv; } > + private: > + int vv; > + }; > + bool await_ready() { return false; } > + void await_suspend(std::coroutine_handle<>) {} > + void await_resume() {} > +}; > + > +extern "C" future > +test () { > + co_return 22; > +} > + > +extern "C" future > +f () noexcept > +{ > + PRINT ("future: about to return"); > + co_return 42; > +} > + > +int main () > +{ > + PRINT ("main: create future"); > + future x = f (); > + PRINT ("main: got future - resuming"); > + if (x.handle.done()) > + __builtin_abort (); > + x.handle.resume(); > + PRINT ("main: after resume"); > + int y = x.handle.promise().get_value(); > + if ( y != 42 ) > + __builtin_abort (); > + if (!x.handle.done()) > + { > + PRINT ("main: apparently not done..."); > + __builtin_abort (); > + } > + PRINT ("main: returning"); > + return 0; > +}