Skip to content

Tail calls with pinned locals #19147

@hyazinthh

Description

@hyazinthh

Opening another issue, since the original is closed and I haven't gotten a response there.

The original problem with pinned arrays seems to be fixed, the tail call is gone when using the newest SDK. However, there are still problems when pinning a local variable:

Repro steps

open Microsoft.FSharp.NativeInterop
open System.Runtime.CompilerServices

module Program =

    [<MethodImpl(MethodImplOptions.NoInlining)>]
    let bar (pValue: nativeptr<int>) : unit =
        let value = NativePtr.read pValue
        printfn "value = %A" value

    [<MethodImpl(MethodImplOptions.NoInlining)>]
    let foo() =
        let mutable value = 42
        use ptr = fixed &value
        bar ptr

    [<EntryPoint>]
    let main argv =
        foo()
        0

The same also happens when using the taking the address directly with the && operator:

    [<MethodImpl(MethodImplOptions.NoInlining)>]
    let foo() =
        let mutable value = 42
        bar &&value

Expected behavior

Should print 42.

Actual behavior

Tail call gets emitted and prints garbage:

 IL_0003: ldloca.s     'value'
 IL_0005: stloc.1      // V_1
 IL_0006: ldloca.s     'value'
 IL_0008: conv.i
 IL_0009: tail.
 IL_000b: call         void Program/Program::bar(int32*)
 IL_0010: ret

Known workarounds

Wrap the bar call in a try finally block.

Related information

  • .NET SDK 10.0.101

Metadata

Metadata

Assignees

Labels

Type

Projects

Status

New

Relationships

None yet

Development

No branches or pull requests

Issue actions