Stack underflow when `if` used in `raise`

Open
#20,564 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
50/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
fsharp
Domain
compilers

Research direction

Start by running the FSI reproduction and comparing the generated IL with the control case; the issue includes the failing repro and ILVerify output. Trace the compiler path for an if expression used as the argument to raise, then verify that the emitted program no longer reports a stack underflow or throws InvalidProgramException.

Written by the indexing model from the issue text.

Description

Area-Compiler-CodeGen Bug Needs-Triage

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
Dominant language
F#
Stars
4.3k
Forks
877
Avg merge
5d 17h
Merged PRs (30d)
139

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from dotnet/fsharp

All issues in dotnet/fsharp

Similar issues

More Compilers issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.