-
Notifications
You must be signed in to change notification settings - Fork 59
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
What happens to the validiy requirements of the return value on a tail call? #491
Comments
Another idea could be that tail-calling a function with a wrong type is UB no matter if it returns a compatible value. That would allow us to check everything when "entering" the tail call and Miri won't need to keep the stack around. (I'm not sure if this is a good idea). Optimization wise I'm not sure we need UB at all though. It seems like to do inlining or to replace tail calls with normal calls you need to know the function body anyway, at which point you can just check if it's called with the right type. |
The way I've conceptualized Maybe it's due to having discussed function call compatibility recently, but this initially smells to me like it should use similar rules. To try to clarify, that the value is "encoded" onto the ABI when returned and "decoded" from the ABI by the call that receives the return; this interpretation would support |
You are contradicting your first paragraph here. With regular |
Ah, sorry; this was actually intentional, but I failed to make it clear why. Obviously, if However, if This is technically still a distinct axis from A very ugly alternative which makes this example UB without requiring the AM to maintain stack context for arbitrary-many " I don't like it, but it would work. Having the AM maintain the stack frames and just optimizing out the frames for the concrete seems a much better approach, and Miri could optimize to not accumulate Another awkward-bad idea: forbid To extract an actual (but still partial) answer to the question of the OP: If If Because I have a strong desire to avoid |
This came up here. @WaffleLapkin provided an example:
As a normal call, there would be UB when
b
returns, since the return place at that moment contains something that is invalid forb
's return type (despite being valid forc
's return type).However, with tail calls,
b
is long gone by the timea
returns.a
returns directly toc
, and both caller and callee see a return type ofu8
. So arguably this program should be allowed? More fundamentally, not allowing this program means that Miri / the spec would have to keep around the return type of all the stack frames that were "popped early" due to tail calls, and ensure that the eventual return type is valid according to all of them -- which seems to go against the very idea of a tail call.The text was updated successfully, but these errors were encountered: