aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@linux.alibaba.com>2020-01-21 12:16:16 +0800
committerBin Cheng <bin.cheng@linux.alibaba.com>2020-01-21 12:16:16 +0800
commitb313d3c49c2387b5e212df22a5e6ecc0c4e95c0a (patch)
treef4dc220f6300557ea83337fa529da0cd118102a2 /gcc
parente0a5b313c1a3edfb33a28b8d8fea92e01490ebb3 (diff)
downloadgcc-b313d3c49c2387b5e212df22a5e6ecc0c4e95c0a.zip
gcc-b313d3c49c2387b5e212df22a5e6ecc0c4e95c0a.tar.gz
gcc-b313d3c49c2387b5e212df22a5e6ecc0c4e95c0a.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/coroutines.cc7
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/coroutines/co-return-warning-1.C48
4 files changed, 64 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ef80482..2dda800 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2020-01-21 Bin Cheng <bin.cheng@linux.alibaba.com>
+
+ * coroutines.cc (finish_co_await_expr): Set return value flag.
+ (finish_co_yield_expr, morph_fn_to_coro): Ditto.
+
2020-01-19 Jason Merrill <jason@redhat.com>
PR c++/33799 - destroy return value, take 2.
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index d3aacd7..8a8c1b9 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 fa457c8..a901cf9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2020-01-20 Bin Cheng <bin.cheng@linux.alibaba.com>
+
+ * g++.dg/coroutines/co-return-warning-1.C: New test.
+
2020-01-21 Kito Cheng <kito.cheng@sifive.com>
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 0000000..69e7690
--- /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 <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 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;
+}
+