The coroutine transformation moves the original function body into a newly created actor function, but the block of the `current_binding_level` still points into the original function, causing the block to be shared between the two functions if it is subsequently used. This may cause havoc later on, as subsequent compiler passes for one function will also implicitly modify the other. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103328#c19 for a more detailed writeup.
This patch fixes the issue locally, but I'm not familiar with the GCC code base so I'm not sure if this is the right way to go about it or if there's a cleaner way to reset the current binding level. If this is the way to go I'm happy to extend the patch with a testcase and changelog entry. --- gcc/cp/coroutines.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index b1bfdc767a4..eb5f80f499b 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -4541,6 +4541,8 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) BLOCK_VARS (top_block) = BIND_EXPR_VARS (ramp_bind); BLOCK_SUBBLOCKS (top_block) = NULL_TREE; + current_binding_level->blocks = top_block; + /* The decl_expr for the coro frame pointer, initialize to zero so that we can pass it to the IFN_CO_FRAME (since there's no way to pass a type, directly apparently). This avoids a "used uninitialized" warning. */ -- 2.32.0