Fix false warning messages about missing return in coroutine.
authorBin Cheng <bin.cheng@linux.alibaba.com>
Tue, 21 Jan 2020 04:16:16 +0000 (12:16 +0800)
committerBin Cheng <bin.cheng@linux.alibaba.com>
Tue, 21 Jan 2020 04:16:16 +0000 (12:16 +0800)
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
gcc/cp/coroutines.cc
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/coroutines/co-return-warning-1.C [new file with mode: 0644]

index ef8048260a313525c3489f6b5b7b4cbc85f716bb..2dda8008f04d8a5ff9934b7aefd4bebacd9cd6ab 100644 (file)
@@ -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.
index d3aacd7ad3b51a00789c267b2ab85a3d7e239cf8..8a8c1b9829b93759573699e06e6458f7c519e860 100644 (file)
@@ -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));
index fa457c86879e137f3886e6dc6b84422447e32ce7..a901cf978412a18f933b1f2c7107491de3e60b75 100644 (file)
@@ -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 (file)
index 0000000..69e7690
--- /dev/null
@@ -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;
+}
+