]> gcc.gnu.org Git - gcc.git/commitdiff
coroutines: Look through NOPs for awaiter variables [PR 99575].
authorIain Sandoe <iain@sandoe.co.uk>
Sat, 2 Oct 2021 11:44:01 +0000 (12:44 +0100)
committerIain Sandoe <iain@sandoe.co.uk>
Sun, 3 Oct 2021 19:41:59 +0000 (20:41 +0100)
There was a missing STRIP_NOPS which meant that, in some cases,
an awaiter variable could be hidden by a view-convert-expr.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
PR c++/99575

gcc/cp/ChangeLog:

* coroutines.cc (build_co_await): Strip NOPs from
candidate awaiter expressions before testing to see
if they need a temporary.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr99575.C: New test.

gcc/cp/coroutines.cc
gcc/testsuite/g++.dg/coroutines/pr99575.C [new file with mode: 0644]

index 2f45575bd92ce13a435b5c00c264dc45e362752f..876a14606f8332f055f9925d9661365a53ce174b 100644 (file)
@@ -1008,6 +1008,7 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind)
     }
 
   /* Only build a temporary if we need it.  */
+  STRIP_NOPS (e_proxy);
   if (TREE_CODE (e_proxy) == PARM_DECL
       || (VAR_P (e_proxy) && !is_local_temp (e_proxy)))
     {
diff --git a/gcc/testsuite/g++.dg/coroutines/pr99575.C b/gcc/testsuite/g++.dg/coroutines/pr99575.C
new file mode 100644 (file)
index 0000000..d5f86c1
--- /dev/null
@@ -0,0 +1,35 @@
+
+#include <coroutine>
+
+class Task {
+ public:
+  struct promise_type {
+    Task get_return_object() { return Task{}; }
+    std::suspend_always initial_suspend() { return {}; }
+    std::suspend_always final_suspend() noexcept { return {}; }
+    void unhandled_exception() {}
+    void return_void() {}
+  };
+
+  bool await_ready() const { return false; }
+  void await_suspend(std::coroutine_handle<void> continuation) {}
+  void await_resume() {}
+};
+
+class NonMoveableTask {
+ public:
+  NonMoveableTask() = default;
+  NonMoveableTask(const NonMoveableTask&) = delete;
+  NonMoveableTask(NonMoveableTask&&) = delete;
+
+  NonMoveableTask& operator=(const NonMoveableTask&) = delete;
+  NonMoveableTask& operator=(NonMoveableTask&& other) = delete;
+
+  bool await_ready() const { return false; }
+  void await_suspend(std::coroutine_handle<void>) {}
+  void await_resume() {}
+};
+
+Task Foo(NonMoveableTask* task) { co_await* task; }
+
+int main() {}
This page took 0.069615 seconds and 5 git commands to generate.