-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
The following code prints a negative number instead of the expected OverflowException under certain conditions:
class Program
{
static uint _value = int.MaxValue + 1U;
static void Main()
{
try
{
var result = CastToIntChecked(_value);
Console.WriteLine(result);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
static int CastToIntChecked(uint value) => checked((int)value);
}
This only seems to happen when CastToIntChecked is inlined. Preventing inlining by running a debug build, applying MethodImplOptions.NoInlining or bloating the method body results in an overflow exception.
Other changes that cause overflow checking to be performed as expected include:
-
calling
CastToIntChecked(int.MaxValue + 1U) -
calling
CastToIntChecked(_value + 1) -
calling
CastToIntChecked(uint.Parse("2147483648")) -
reading
_valueinsideCastToIntCheckedinstead of passing it in as an argument -
performing other overflowing conversions like
ulong->longorulong->int
I haven't been able to extensively determine the affected runtimes, but as far as I can tell this occurs at least on Windows builds of .NET Core 2.2, 3.0-preview5, as well as .NET Desktop x64 but not .NET Desktop x86.