-
Notifications
You must be signed in to change notification settings - Fork 5.3k
JIT: Disallow widening tailcalls in async functions #119145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The JIT allows tailcalls that depend on widening happening in the callee: e.g. an int32 returning function can tailcall an int16 returning function because the managed ABI specifies that the callee will widen anyway. However, this is not legal for async methods. For async methods the int32 and int16 returning functions come with two different resumption stubs that are responsible for propagating the returned result into the next continuation in asynchronous cases. Allowing an int32 -> int16 tailcall means only a 16-bit value gets propagated into a caller that expects 32 bits to be written into its continuation. Fix dotnet#119060
|
PTAL @dotnet/jit-contrib |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes a JIT compilation issue where widening tailcalls were incorrectly allowed in async functions. The problem occurs when an async function returning a wider type (e.g., int32) attempts to tailcall an async function returning a narrower type (e.g., int16), which can corrupt the continuation mechanism in async execution.
Key changes:
- Modified JIT logic to disallow widening tailcalls specifically for async functions
- Added comprehensive test case demonstrating the problematic scenario
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/coreclr/jit/importercalls.cpp | Added check to prevent widening tailcalls in async functions |
| src/tests/async/widening-tailcall/widening-tailcall.cs | Test case reproducing the async widening tailcall bug |
| src/tests/async/widening-tailcall/widening-tailcall.csproj | Project file for the new test |
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
|
/ba-g Deadlettered |
|
/backport to release/10.0 |
|
Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/17299660780 |
The JIT allows tailcalls that depend on widening happening in the callee: e.g. an int32 returning function can tailcall an int16 returning function because the managed ABI specifies that the callee will widen anyway.
However, this is not legal for async methods. For async methods the int32 and int16 returning functions come with two different resumption stubs that are responsible for propagating the returned result into the next continuation in asynchronous cases. Allowing an int32 -> int16 tailcall means only a 16-bit value gets propagated into a caller that expects 32 bits to be written into its continuation.
Fix #119060