diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2020-04-28 00:27:47 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2020-04-28 02:07:37 +0100 |
commit | b9c91b7f3279e23aed965c05197acf3b6f439f8d (patch) | |
tree | f1defb0510f253de446d9aa6875ab7a5772c0a0a /libstdc++-v3 | |
parent | 5726da6bdcdc58c44eafd60814aee074bf9d835a (diff) | |
download | gcc-b9c91b7f3279e23aed965c05197acf3b6f439f8d.zip gcc-b9c91b7f3279e23aed965c05197acf3b6f439f8d.tar.gz gcc-b9c91b7f3279e23aed965c05197acf3b6f439f8d.tar.bz2 |
coroutines: Fix handling of non-class coroutine returns [PR94759]
From the standard:
The header <coroutine> defines the primary template coroutine_traits
such that if ArgTypes is a parameter pack of types and if the
qualified-id R::promise_type is valid and denotes a type, then
coroutine_traits<R,ArgTypes...> has the following publicly accessible
member:
using promise_type = typename R::promise_type;
this should not prevent more specialised cases and the following
code should be accepted, but is currently rejected with:
'error: coroutine return type ‘void’ is not a class'
This is because the check for non-class-ness of the return value was
in the wrong place; it needs to be carried out in a SFINAE context.
The following patch removes the restriction in the traits template
instantiation and allows for the case that the ramp function could
return void.
The <coroutine> header is amended to implement the required
functionality.
gcc/cp/ChangeLog:
2020-04-28 Iain Sandoe <iain@sandoe.co.uk>
PR c++/94759
* coroutines.cc (coro_promise_type_found_p): Do not
exclude non-classes here (this needs to be handled in the
coroutine header).
(morph_fn_to_coro): Allow for the case where the coroutine
returns void.
gcc/testsuite/ChangeLog:
2020-04-28 Iain Sandoe <iain@sandoe.co.uk>
PR c++/94759
* g++.dg/coroutines/coro-bad-alloc-00-bad-op-new.C: Adjust for
updated error messages.
* g++.dg/coroutines/coro-bad-alloc-01-bad-op-del.C: Likewise.
* g++.dg/coroutines/coro-bad-alloc-02-no-op-new-nt.C: Likewise.
* g++.dg/coroutines/coro-missing-promise.C: Likewise.
* g++.dg/coroutines/pr93458-5-bad-coro-type.C: Liekwise.
* g++.dg/coroutines/torture/co-ret-17-void-ret-coro.C: New test.
libstdc++-v3/ChangeLog:
2020-04-28 Jonathan Wakely <jwakely@redhat.com>
Iain Sandoe <iain@sandoe.co.uk>
PR c++/94759
* include/std/coroutine: Implement handing for non-
class coroutine return types.
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 7 | ||||
-rw-r--r-- | libstdc++-v3/include/std/coroutine | 15 |
2 files changed, 19 insertions, 3 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b3d001c..f6de19d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2020-04-28 Jonathan Wakely <jwakely@redhat.com> + Iain Sandoe <iain@sandoe.co.uk> + + PR c++/94759 + * include/std/coroutine: Implement handing for non- + class coroutine return types. + 2020-04-24 Jonathan Wakely <jwakely@redhat.com> * include/experimental/executor (service_already_exists): Make default diff --git a/libstdc++-v3/include/std/coroutine b/libstdc++-v3/include/std/coroutine index 4fa1355..b40a3bc 100644 --- a/libstdc++-v3/include/std/coroutine +++ b/libstdc++-v3/include/std/coroutine @@ -63,12 +63,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 17.12.2 coroutine traits /// [coroutine.traits] /// [coroutine.traits.primary] - template <typename _Result, typename...> - struct coroutine_traits + /// If _Result::promise_type is valid and denotes a type then the traits + /// have a single publicly accessible member, otherwise they are empty. + template <typename _Result, typename = void> + struct __coroutine_traits_impl {}; + + template <typename _Result> + struct __coroutine_traits_impl<_Result, + __void_t<typename _Result::promise_type>> { - using promise_type = typename _Result::promise_type; + using promise_type = typename _Result::promise_type; }; + template <typename _Result, typename...> + struct coroutine_traits : __coroutine_traits_impl<_Result> {}; + // 17.12.3 Class template coroutine_handle /// [coroutine.handle] template <typename _Promise = void> |