Instantiating an exception with wrong payload compiles and fails at run-time
It is possible to instantiate a user defined exception by giving an interpolated string (without anything interpolated) as a constructor argument without compile-time error although the constructor expects something else.
Note that the problem does not reproduce (i.e. compile error is given as expected) if normal string is used instead of interpolated string or something is interpolated in the interpolated string.
Repro steps
- Create new console application
- Add the code below to Program.fs
- Run
dotnet run
type Foo = { Bar: int }
exception MyException of string * Foo
try
raise (MyException($"BOOM"))
// raise (MyException("BOOM")) // <- Compile-time error
// raise (MyException($"BOOM {42}")) // <- Compile-time error
with
| MyException(msg, foo) ->
printfn "%A" foo
Expected behavior
Code should not compile.
Actual behavior
Code compiles, but fails at run-time with following error:
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.Runtime.CompilerServices.CastHelpers.ChkCastAny(Void*, System.Object)
at Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions.UnboxGeneric[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Object)
at Microsoft.FSharp.Core.PrintfImpl+GenericToString@969-3[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Invoke(System.Object)
at Microsoft.FSharp.Core.PrintfImpl+OneStepWithArg@501-1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Invoke(System.__Canon)
at <StartupCode$ExceptionErrorReproduction>.$Program.main@()
Related information
- Operating system: macOS 12.3.1
- .NET SDK version: 6.0.302
Yeah, we should fix it
This is even easier to repro underlying issue:
let foo:int = $"a"
will result in the following codegen for foo
IL_0000: ldstr ""
IL_0005: ret
however foo is int32
.method public specialname static int32 get_foo