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

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.
This commit is contained in:
Iain Sandoe 2020-06-26 10:52:07 +01:00
parent 5b959c22bc
commit e195c8045a
3 changed files with 24 additions and 1 deletions

View file

@ -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 functions name is looked up in the scope of the promise

View file

@ -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} }

View file

@ -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);