[pushed] coroutines: Handle bad g-r-o-o-a-f cases.

Message ID 0650F16A-0DF7-4B17-9280-C3EEC959A7FE@sandoe.co.uk
State New
Headers show
Series
  • [pushed] coroutines: Handle bad g-r-o-o-a-f cases.
Related show

Commit Message

Iain Sandoe June 26, 2020, 11:42 a.m.
Hi

This fixes an ice-on-invalid I found while working on other
cases.

tested on x86_64-linux, darwin, powerpc64-linux
applied to master as obvious/trivial.
thanks
Iain

-------

If we see a get_return_object_on_allocation_failure in the
promise, we expect to be able to use it.  If this isn't
possible (because of some error in the declaration) then we
need to handle the erroneous return to allow following code
to complete.

gcc/cp/ChangeLog:

	* coroutines.cc (morph_fn_to_coro): Handle error
	returns in building g-r-o-o-a-f expressions.

gcc/testsuite/ChangeLog:

	* g++.dg/coroutines/coro1-allocators.h (BAD_GROOAF_STATIC):
	New.
	* g++.dg/coroutines/coro-bad-grooaf-00-static.C: New test.
---
 gcc/cp/coroutines.cc                              |  5 +++++
 .../g++.dg/coroutines/coro-bad-grooaf-00-static.C | 15 +++++++++++++++
 .../g++.dg/coroutines/coro1-allocators.h          |  5 ++++-
 3 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/coroutines/coro-bad-grooaf-00-static.C

-- 
2.24.1

Patch

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 64b97535c8d..ad276592231 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3932,6 +3932,11 @@  morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
 				    NULL_TREE, LOOKUP_NORMAL, NULL,
 				    tf_warning_or_error);
 
+  /* ... but if that fails, returning an error, the later stages can't handle
+     the erroneous expression, so we reset the call as if it was absent.  */
+  if (grooaf == error_mark_node)
+    grooaf = NULL_TREE;
+
   /* Allocate the frame, this has several possibilities:
      [dcl.fct.def.coroutine] / 9 (part 1)
      The allocation function’s name is looked up in the scope of the promise
diff --git a/gcc/testsuite/g++.dg/coroutines/coro-bad-grooaf-00-static.C b/gcc/testsuite/g++.dg/coroutines/coro-bad-grooaf-00-static.C
new file mode 100644
index 00000000000..e7d04346d57
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/coro-bad-grooaf-00-static.C
@@ -0,0 +1,15 @@ 
+/* g-r-o-o-a-f should be static.  */
+
+#define BAD_GROOAF_STATIC
+#define PROVIDE_GROOAF
+#include "coro1-allocators.h"
+
+int used_grooaf = 0;
+
+struct coro1
+f () noexcept
+{
+  PRINT ("coro1: about to return");
+  co_return;
+} // { dg-error {cannot call member function 'coro1 coro1::promise_type::get_return_object_on_allocation_failure\(\)' without object} }
+
diff --git a/gcc/testsuite/g++.dg/coroutines/coro1-allocators.h b/gcc/testsuite/g++.dg/coroutines/coro1-allocators.h
index 3d869106006..f7a85e9e671 100644
--- a/gcc/testsuite/g++.dg/coroutines/coro1-allocators.h
+++ b/gcc/testsuite/g++.dg/coroutines/coro1-allocators.h
@@ -172,8 +172,11 @@  struct coro1 {
   }
 #endif
 
+#ifndef BAD_GROOAF_STATIC
+# define BAD_GROOAF_STATIC static
+#endif
 #ifdef PROVIDE_GROOAF
-  static coro1 get_return_object_on_allocation_failure () noexcept {
+  BAD_GROOAF_STATIC coro1 get_return_object_on_allocation_failure () noexcept {
     PRINT ("alloc fail return");
     used_grooaf++;
     return coro1 (nullptr);