coroutines: Add a test for non-trivial await_resume return type.
authorIain Sandoe <iain@sandoe.co.uk>
Sat, 29 Feb 2020 20:45:31 +0000 (20:45 +0000)
committerIain Sandoe <iain@sandoe.co.uk>
Sat, 29 Feb 2020 20:46:15 +0000 (20:46 +0000)
Improve test coverage.

gcc/testsuite/ChangeLog:

2020-02-29  Iain Sandoe  <iain@sandoe.co.uk>

* g++.dg/coroutines/coro1-ret-int-yield-int.h: Add templated
awaitable.
* g++.dg/coroutines/torture/co-await-15-return-non-triv.C: New test.

gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/coroutines/coro1-ret-int-yield-int.h
gcc/testsuite/g++.dg/coroutines/torture/co-await-15-return-non-triv.C [new file with mode: 0644]

index 2d0d9c6..e38f2c8 100644 (file)
@@ -1,3 +1,9 @@
+2020-02-29 Iain Sandoe <iain@sandoe.co.uk>
+
+       * g++.dg/coroutines/coro1-ret-int-yield-int.h: Add templated
+       awaitable.
+       * g++.dg/coroutines/torture/co-await-15-return-non-triv.C: New test.
+
 2020-02-29  John David Anglin  <danglin@gcc.gnu.org>
 
        PR ada/91100
index abf6258..67ac197 100644 (file)
@@ -78,6 +78,16 @@ struct coro1 {
     int& await_resume() const noexcept { PRINT ("susp-always-resume-intprt"); return x;}
   };
 
+  template <typename _AwaitType>
+  struct suspend_always_tmpl_awaiter {
+    _AwaitType x;
+    suspend_always_tmpl_awaiter(_AwaitType __x) : x(__x) {}
+    ~suspend_always_tmpl_awaiter() {}
+    bool await_ready() const noexcept { return false; }
+    void await_suspend(coro::coroutine_handle<>) const noexcept { PRINT ("suspend_always_tmpl_awaiter");}
+    _AwaitType await_resume() const noexcept { PRINT ("suspend_always_tmpl_awaiter"); return x;}
+  };
+
   struct promise_type {
 
   promise_type() : vv(-1) {  PRINT ("Created Promise"); }
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/co-await-15-return-non-triv.C b/gcc/testsuite/g++.dg/coroutines/torture/co-await-15-return-non-triv.C
new file mode 100644 (file)
index 0000000..70c974b
--- /dev/null
@@ -0,0 +1,51 @@
+//  { dg-do run }
+
+/* Check that we handle await_resume for a non-trivial type.  */
+
+#include "../coro.h"
+
+// boiler-plate for tests of codegen
+#include "../coro1-ret-int-yield-int.h"
+
+coro1
+f ()
+{
+  struct test {
+    int a;
+    ~test () {}
+  };
+  test input{5};
+  test res = co_await coro1::suspend_always_tmpl_awaiter<test>(input);
+  co_return res.a + 10;
+}
+
+int main ()
+{
+  PRINT ("main: create coro1");
+  struct coro1 f_coro = f ();
+
+  if (f_coro.handle.done())
+    {
+      PRINT ("main: we should not be 'done' [1]");
+      abort ();
+    }
+  PRINT ("main: resuming [1] initial suspend");
+  f_coro.handle.resume();
+  PRINT ("main: resuming [2] co_await suspend_always_tmpl_awaiter");
+  f_coro.handle.resume();
+
+  /* we should now have returned with the co_return (15) */
+  if (!f_coro.handle.done())
+    {
+      PRINT ("main: we should be 'done' ");
+      abort ();
+    }
+  int y = f_coro.handle.promise().get_value();
+  if (y != 15)
+    {
+      PRINTF ("main: y is wrong : %d, should be 15\n", y);
+      abort ();
+    }
+  PRINT ("main: done");
+  return 0;
+}