diff mbox series

[pushed] coroutines: Await expressions are not allowed in handlers [PR 99710].

Message ID 20211003195630.67604-1-iain@sandoe.co.uk
State New
Headers show
Series [pushed] coroutines: Await expressions are not allowed in handlers [PR 99710]. | expand

Commit Message

Iain Sandoe Oct. 3, 2021, 7:56 p.m. UTC
Hi,

C++20 [expr.await] / 2
An await-expression shall appear only in a potentially-evaluated expression
within the compound-statement of a function-body outside of a handler.

tested on x86_64, powerpc64le-linux, x86_64-darwin, cppcoro and folly,
pushed to master as obvious, thanks
Iain

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>

	PR c++/99710

gcc/cp/ChangeLog:

	* coroutines.cc (await_statement_walker): Report an error if
	an await expression is found in a handler body.

gcc/testsuite/ChangeLog:

	* g++.dg/coroutines/pr99710.C: New test.
---
 gcc/cp/coroutines.cc                      | 17 ++++++++++++++-
 gcc/testsuite/g++.dg/coroutines/pr99710.C | 25 +++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/coroutines/pr99710.C
diff mbox series

Patch

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 1dd9abd1e1f..377b90c777f 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3688,7 +3688,22 @@  await_statement_walker (tree *stmt, int *do_subtree, void *d)
 	    *do_subtree = 0;
 	    return res;
 	  }
-	break;
+	  break;
+	case HANDLER:
+	  {
+	    /* [expr.await] An await-expression shall appear only in a
+	       potentially-evaluated expression within the compound-statement
+	       of a function-body outside of a handler.  */
+	    tree *await_ptr;
+	    hash_set<tree> visited;
+	    if (!(cp_walk_tree (&HANDLER_BODY (expr), find_any_await,
+		  &await_ptr, &visited)))
+	      return NULL_TREE; /* All OK.  */
+	    location_t loc = EXPR_LOCATION (*await_ptr);
+	    error_at (loc, "await expressions are not permitted in handlers");
+	    return NULL_TREE; /* This is going to fail later anyway.  */
+	  }
+	  break;
       }
   else if (EXPR_P (expr))
     {
diff --git a/gcc/testsuite/g++.dg/coroutines/pr99710.C b/gcc/testsuite/g++.dg/coroutines/pr99710.C
new file mode 100644
index 00000000000..e4f7116b8d7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr99710.C
@@ -0,0 +1,25 @@ 
+#include <coroutine>
+
+struct task {
+    struct promise_type {
+        std::suspend_always initial_suspend();
+        std::suspend_always final_suspend() noexcept;
+        task get_return_object();
+        void return_void();
+        void unhandled_exception();
+    };
+};
+
+task
+my_coro ()
+{
+  try
+    { }
+  catch (...)
+    {
+      // [expr.await] An await-expression shall appear only in a potentially-
+      // evaluated expression within the compound-statement of a function-body
+      // outside of a handler 
+      co_await std::suspend_always{}; // { dg-error "await expressions are not permitted in handlers" }
+    }
+}