From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp002.apm-internet.net (smtp002.apm-internet.net [85.119.248.221]) by sourceware.org (Postfix) with ESMTPS id BD77F382FADC for ; Sat, 17 Dec 2022 13:40:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BD77F382FADC Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=sandoe.co.uk Authentication-Results: sourceware.org; spf=none smtp.mailfrom=sandoe.co.uk Received: (qmail 75558 invoked from network); 17 Dec 2022 13:40:31 -0000 X-APM-Out-ID: 16712844317555 X-APM-Authkey: 257869/1(257869/1) 2 Received: from unknown (HELO smtpclient.apple) (81.138.1.83) by smtp002.apm-internet.net with SMTP; 17 Dec 2022 13:40:31 -0000 Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.1\)) Subject: Re: [PATCH v2] coroutines: Accept 'extern "C"' coroutines. From: Iain Sandoe In-Reply-To: <20221210113744.38708-1-iain@sandoe.co.uk> Date: Sat, 17 Dec 2022 13:40:30 +0000 Cc: Jason Merrill Content-Transfer-Encoding: quoted-printable Message-Id: <0FD0D3D2-EB28-41DD-9F08-BD8BB267F238@sandoe.co.uk> References: <20221210113744.38708-1-iain@sandoe.co.uk> To: GCC Patches X-Mailer: Apple Mail (2.3696.120.41.1.1) X-Spam-Status: No, score=-14.2 required=5.0 tests=BAYES_00,GIT_PATCH_0,KAM_COUK,KAM_DMARC_STATUS,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_LOW,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: 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 =E2=80=94 8< =E2=80=94 '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 =3D DECL_RAMP_FN (decl)) + { + if (DECL_ACTOR_FN (ramp) =3D=3D decl) + write_string (JOIN_STR "actor"); + else if (DECL_DESTROY_FN (ramp) =3D=3D decl) + write_string (JOIN_STR "destroy"); + else + gcc_unreachable (); + } } =20 /* 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); =20 - /* If this is a coroutine helper, then append an appropriate = string to - identify which. */ - if (tree ramp =3D DECL_RAMP_FN (decl)) - { - if (DECL_ACTOR_FN (ramp) =3D=3D decl) - write_string (JOIN_STR "actor"); - else if (DECL_DESTROY_FN (ramp) =3D=3D decl) - write_string (JOIN_STR "destroy"); - else - gcc_unreachable (); - } } } =20 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 =3D std::coroutine_handle; + handle_type handle; + future () : handle(0) {} + future (handle_type _handle) + : handle(_handle) { + PRINT("Created future object from handle"); + } + future (const future &) =3D delete; // no copying + future (future &&s) : handle(s.handle) { + s.handle =3D nullptr; + PRINT("future mv ctor "); + } + future &operator =3D (future &&s) { + handle =3D s.handle; + s.handle =3D nullptr; + PRINT("future op=3D "); + 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 =3D 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);} + =20 + 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 =3D f (); + PRINT ("main: got future - resuming"); + if (x.handle.done()) + __builtin_abort (); + x.handle.resume(); + PRINT ("main: after resume"); + int y =3D x.handle.promise().get_value(); + if ( y !=3D 42 ) + __builtin_abort (); + if (!x.handle.done()) + { + PRINT ("main: apparently not done..."); + __builtin_abort (); + } + PRINT ("main: returning"); + return 0; +} --=20 2.37.1 (Apple Git-137.1)