coroutines, testsuite: Add test for fixed pr [PR94288]
authorIain Sandoe <iain@sandoe.co.uk>
Fri, 24 Apr 2020 08:17:06 +0000 (09:17 +0100)
committerIain Sandoe <iain@sandoe.co.uk>
Fri, 24 Apr 2020 12:47:31 +0000 (13:47 +0100)
This is a version of the reproducer in the PR, usable on
multiple platforms.

gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/coroutines/pr94288.C [new file with mode: 0644]

index e6b8812061debf305fdb4bc28297163caf50c53b..33edc25076d966d0b1e90b48ff69bf90ca8628a8 100644 (file)
@@ -1,3 +1,8 @@
+2020-04-24 Iain Sandoe <iain@sandoe.co.uk>
+
+       PR c++/94288
+       * g++.dg/coroutines/pr94288.C: New test.
+
 2020-04-24  Alexandre Oliva <oliva@adacore.com>
 
        * lib/target-supports.exp (check_effective_target_fileio): New.
diff --git a/gcc/testsuite/g++.dg/coroutines/pr94288.C b/gcc/testsuite/g++.dg/coroutines/pr94288.C
new file mode 100644 (file)
index 0000000..2557e3e
--- /dev/null
@@ -0,0 +1,70 @@
+//  { dg-additional-options  "-w" }
+
+#include "coro.h"
+
+#include <vector>
+
+template <typename T> struct promise {
+  T _value;
+  coro::coroutine_handle<> _continuation = nullptr;
+
+  struct final_awaitable {
+    bool _has_continuation;
+    final_awaitable(bool has_continuation)
+        : _has_continuation(has_continuation) {}
+
+    bool await_ready() const noexcept { return !_has_continuation; }
+
+    template <typename Promise>
+    coro::coroutine_handle<>
+    await_suspend(coro::coroutine_handle<Promise> coro) noexcept {
+      return coro.promise()._continuation;
+    }
+
+    void await_resume() noexcept {}
+  };
+
+  auto get_return_object() noexcept {
+    return coro::coroutine_handle<promise>::from_promise(*this);
+  }
+
+  auto initial_suspend() noexcept { return coro::suspend_always(); }
+
+  auto final_suspend() noexcept {
+    return final_awaitable(_continuation != nullptr);
+  }
+
+  void return_value(T value) { _value = value; }
+
+  void unhandled_exception() { /*std::terminate();*/ }
+
+};
+
+template <typename T> struct task {
+  using promise_type = promise<T>;
+  coro::coroutine_handle<promise<T>> _handle;
+
+  task(coro::coroutine_handle<promise<T>> handle) : _handle(handle) {}
+
+  bool await_ready() noexcept { return _handle.done(); }
+
+  coro::coroutine_handle<>
+  await_suspend(coro::coroutine_handle<> handle) noexcept {
+    _handle.promise()._continuation = handle;
+    return _handle;
+  }
+
+  T await_resume() noexcept { return _handle.promise()._value; }
+};
+
+task<std::vector<int>> foo()
+{
+  co_return std::vector<int>();
+}
+
+task<int> bar()
+{
+  while ((co_await foo()).empty()) {
+  }
+  co_return 0;
+}