diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2020-01-21 20:42:17 +0000 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2020-01-21 20:57:30 +0000 |
commit | a312c80194685790aec7cf678eba83a536031cbf (patch) | |
tree | 80541e1c9df1ce219287468f736a8f2042f336f8 /gcc | |
parent | bd0a3e244d94ad4a5e41f01ebf285f0861cb4a03 (diff) | |
download | gcc-a312c80194685790aec7cf678eba83a536031cbf.zip gcc-a312c80194685790aec7cf678eba83a536031cbf.tar.gz gcc-a312c80194685790aec7cf678eba83a536031cbf.tar.bz2 |
[coro] Fix co_await of void type.
gcc/cp
2020-01-21 Iain Sandoe <iain@sandoe.co.uk>
Bin Cheng <bin.cheng@linux.alibaba.com>
* coroutines.cc (coro_promise_type_found_p): Check for NULL return
from complete_type_or_else.
(register_param_uses): Likewise.
(build_co_await): Do not try to use complete_type_or_else for void
types, otherwise for incomplete types, check for NULL return from
complete_type_or_else.
gcc/testsuite
2020-01-21 Bin Cheng <bin.linux@linux.alibaba.com>
* g++.dg/coroutines/co-await-void_type.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/coroutines.cc | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/co-await-void_type.C | 44 |
4 files changed, 71 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 412702f..3fc1b31 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2020-01-21 Iain Sandoe <iain@sandoe.co.uk> + Bin Cheng <bin.cheng@linux.alibaba.com> + + * coroutines.cc (coro_promise_type_found_p): Check for NULL return + from complete_type_or_else. + (register_param_uses): Likewise. + (build_co_await): Do not try to use complete_type_or_else for void + types, otherwise for incomplete types, check for NULL return from + complete_type_or_else. + 2020-01-21 Jason Merrill <jason@redhat.com> PR c++/91476 - anon-namespace reference temp clash between TUs. diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 8a8c1b9..b99e721 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -428,8 +428,9 @@ coro_promise_type_found_p (tree fndecl, location_t loc) /* Complete this, we're going to use it. */ coro_info->handle_type = complete_type_or_else (handle_type, fndecl); + /* Diagnostic would be emitted by complete_type_or_else. */ - if (coro_info->handle_type == error_mark_node) + if (!coro_info->handle_type) return false; /* Build a proxy for a handle to "self" as the param to @@ -633,7 +634,13 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind) else o = a; /* This is most likely about to fail anyway. */ - tree o_type = complete_type_or_else (TREE_TYPE (o), o); + tree o_type = TREE_TYPE (o); + if (o_type && !VOID_TYPE_P (o_type)) + o_type = complete_type_or_else (o_type, o); + + if (!o_type) + return error_mark_node; + if (TREE_CODE (o_type) != RECORD_TYPE) { error_at (loc, "awaitable type %qT is not a structure", @@ -2730,6 +2737,10 @@ register_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d) if (!COMPLETE_TYPE_P (actual_type)) actual_type = complete_type_or_else (actual_type, *stmt); + if (actual_type == NULL_TREE) + /* Diagnostic emitted by complete_type_or_else. */ + actual_type = error_mark_node; + if (TREE_CODE (actual_type) == REFERENCE_TYPE) actual_type = build_pointer_type (TREE_TYPE (actual_type)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e8561cc..f4f11a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2020-01-21 Bin Cheng <bin.linux@linux.alibaba.com> + + * g++.dg/coroutines/co-await-void_type.C: New test. + 2020-01-21 Jakub Jelinek <jakub@redhat.com> PR target/93333 diff --git a/gcc/testsuite/g++.dg/coroutines/co-await-void_type.C b/gcc/testsuite/g++.dg/coroutines/co-await-void_type.C new file mode 100644 index 0000000..0bb8818 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/co-await-void_type.C @@ -0,0 +1,44 @@ +// { dg-additional-options "-std=c++17 -fsyntax-only -w" } + +#include <coroutine> + +class resumable { +public: + struct promise_type; + using coro_handle = std::coroutine_handle<promise_type>; + resumable(coro_handle handle) : handle_(handle) {} + resumable(resumable&) = delete; + resumable(resumable&&) = delete; + bool resume() { + if (not handle_.done()) + handle_.resume(); + return not handle_.done(); + } + int recent_val(); + ~resumable() { handle_.destroy(); } +private: + coro_handle handle_; +}; + +struct resumable::promise_type { + int value_; + + using coro_handle = std::coroutine_handle<promise_type>; + auto get_return_object() { + return coro_handle::from_promise(*this); + } + auto initial_suspend() { return std::suspend_always(); } + auto final_suspend() { return std::suspend_always(); } + void yield_value(int v) { value_ = v; } + void unhandled_exception() {} +}; + +int resumable::recent_val(){return handle_.promise().value_;} + +resumable foo(int n){ + int x = 1; + co_await std::suspend_always(); + int y = 2; + co_yield n + x + y; // { dg-error "awaitable type 'void' is not a structure" } +} + |