Closed
Description
The JIT inlines delegate calls, which is done in lowering by inserting indirections to fetch the instance and target from the delegate object. However, the indirection that fetches the instance is inserted right after the existing 'this' argument node. This can reorder the null-check of the delegate object with exceptions thrown by other arguments.
For example, the following example throws NullReferenceException
in release. It should throw DivisionByZeroException
(as it does in debug).
public static void Main()
{
Test(0);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void Test(int i)
{
GetAction()(100 / i);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static Action<int> GetAction() => null;
category:correctness
theme:delegates
skill-level:intermediate
cost:small
impact:small