Skip to content

Stack underflow when if used in raise #20564

Description

@kerams

Repro steps

// run in fsi
open System

let repro (b: bool) = Math.Max (1, raise (Exception (if b then "x" else "y")))

let control (b: bool) = Math.Max (1, String.length (if b then "x" else "y"))

try control true |> ignore; printfn "control: ok" with ex -> printfn "control: %s" (ex.GetType().Name)
try repro true |> ignore; printfn "repro: ok" with ex -> printfn "repro: %s" (ex.GetType().Name)

The original production code looked like

try
    ...
with ...  ->
    return raise (SerializationException (if data.Length > 0 then int data.[0] else 0, "index out of range"))

Expected behavior

control: ok
repro: ok

Actual behavior

control: ok
System.InvalidProgramException: Common Language Runtime detected an invalid program.

ILVerify reports [StackUnderflow] Repro::repro(bool) offset 0x0D

IL_0000: ldc.i4.1
IL_0001: ldc.i4.0
IL_0002: brfalse.s    IL_000c
IL_0004: ldnull
IL_0005: unbox.any    [System.Runtime]System.Int32
IL_000a: br.s         IL_0033
IL_000c: stloc.0      // V_0
IL_000d: stloc.1      // V_1 <- saves a second value, but only one is on the stack -> underflow

Known workarounds

Bind the argument first.

Related information

  • Win 11, SDK 11.0.100-rc.1.26425.128

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions