From b313d3c49c2387b5e212df22a5e6ecc0c4e95c0a Mon Sep 17 00:00:00 2001 From: Bin Cheng Date: Tue, 21 Jan 2020 12:16:16 +0800 Subject: [PATCH] Fix false warning messages about missing return in coroutine. The patch sets current_function_returns_value flag in templates for all co_return/co_yield/co_await cases, as well as for ramp function. gcc/cp/ChangeLog * coroutines.cc (finish_co_await_expr): Set return value flag. (finish_co_yield_expr, morph_fn_to_coro): Ditto. gcc/testsuite/ChangeLog * g++.dg/coroutines/co-return-warning-1.C: New test. --- gcc/cp/ChangeLog | 5 ++ gcc/cp/coroutines.cc | 7 +++ gcc/testsuite/ChangeLog | 4 ++ .../g++.dg/coroutines/co-return-warning-1.C | 48 +++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 gcc/testsuite/g++.dg/coroutines/co-return-warning-1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ef8048260a3..2dda8008f04 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2020-01-21 Bin Cheng + + * coroutines.cc (finish_co_await_expr): Set return value flag. + (finish_co_yield_expr, morph_fn_to_coro): Ditto. + 2020-01-19 Jason Merrill PR c++/33799 - destroy return value, take 2. diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index d3aacd7ad3b..8a8c1b9829b 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -753,6 +753,8 @@ finish_co_await_expr (location_t kw, tree expr) if (processing_template_decl) { + current_function_returns_value = 1; + if (check_for_bare_parameter_packs (expr)) return error_mark_node; @@ -826,6 +828,8 @@ finish_co_yield_expr (location_t kw, tree expr) if (processing_template_decl) { + current_function_returns_value = 1; + if (check_for_bare_parameter_packs (expr)) return error_mark_node; @@ -2870,6 +2874,9 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) if (!coro_function_valid_p (orig)) return false; + /* The ramp function does return a value. */ + current_function_returns_value = 1; + /* 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)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fa457c86879..a901cf97841 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2020-01-20 Bin Cheng + + * g++.dg/coroutines/co-return-warning-1.C: New test. + 2020-01-21 Kito Cheng PR target/93304 diff --git a/gcc/testsuite/g++.dg/coroutines/co-return-warning-1.C b/gcc/testsuite/g++.dg/coroutines/co-return-warning-1.C new file mode 100644 index 00000000000..69e7690bb97 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/co-return-warning-1.C @@ -0,0 +1,48 @@ +// { dg-additional-options "-std=c++17 -w" } + +#include + +class resumable { +public: + struct promise_type; + using coro_handle = std::coroutine_handle; + 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; + 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 return_value(int v) { value_ = v; } + std::suspend_always yield_value(int v) { + value_ = v; + return std::suspend_always(); + } + 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; +} + -- 2.30.2