[clang] [Clang][Coroutines] Insert coroutine param fake uses before llvm.coro.free (PR #194690)

Stephen Tozer via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 29 07:57:14 PDT 2026


SLTozer wrote:

> Here, InstCombine sinks `%b8` to the beginning of the `coro.ret` block. Since this may cross a suspending point, CoroSplit rewrites `%b8` as a load from the coroutine frame. This causes a heap-use-after-free if `%b8` is false. The problem could be solved either by preventing InstCombine from moving instructions across `coro.free`, or by aggressively sinking them after `coro.end`. However, I'm still unsure how to achieve this.

I did think that the rewrites were incorrect; my assumption was that there is an implicit assumption in CoroSplit (or elsewhere) that parameters to the coroutine (other than `this`) won't be used after the coroutine frame is freed (because no user code will be executed at that point). 

> If you simply don't want something to be on the frame, you can use "coro.outside.frame" metadata.

!coro.outside.frame is applied to `%b.addr`; this metadata is dropped when SROA removes the alloca and replaces it with direct uses of `%b`. `%b` is spilled into the coroutine frame later during CoroSplit.

In principle, I think the ideal behaviour is that using `-fextend-variable-liveness` with coroutines would prevent the optimizer from removing the values of variables that only exist between suspend points, or any optimizations (I'm not sure if there are any) that might skip storing unused values back to the coroutine frame - does that sound like a reasonable objective? Right now though, I think given the relative complexity and the fact that parameters will largely always be saved to the coroutine frame, skipping generating fake uses for coroutine parameters would be reasonable.

https://github.com/llvm/llvm-project/pull/194690


More information about the cfe-commits mailing list