Skip to content

Commit

Permalink
JIT: Expand inlined delegate calls in correct order (#89175)
Browse files Browse the repository at this point in the history
The access of the target instance was incorrectly inserted right after
the location of the delegate instance. Since this indirection can throw
a NRE this is incorrect; to get the proper inlined behavior, the
indirection must happen only after all arguments have been evaluated.

Fix #75832
  • Loading branch information
jakobbotsch authored Jul 20, 2023
1 parent 4cbf8bd commit 3db5172
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4958,9 +4958,14 @@ GenTree* Lowering::LowerDelegateInvoke(GenTreeCall* call)

GenTree* newThis = comp->gtNewIndir(TYP_REF, newThisAddr);

BlockRange().InsertAfter(thisExpr, newThisAddr, newThis);

// Insert the new 'this' arg right before the call to get the correct null
// behavior (the NRE that would logically happen inside Delegate.Invoke
// should happen after all args are evaluated). We must also move the
// PUTARG_REG node ahead.
thisArgNode->AsOp()->gtOp1 = newThis;
BlockRange().Remove(thisArgNode);
BlockRange().InsertBefore(call, newThisAddr, newThis, thisArgNode);

ContainCheckIndir(newThis->AsIndir());

// the control target is
Expand Down
38 changes: 38 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_75832/Runtime_75832.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.CompilerServices;
using Xunit;

public class Runtime_75832
{
[Fact]
public static int TestEntryPoint()
{
try
{
Test(0);
Console.WriteLine("FAIL: No exception thrown");
}
catch (DivideByZeroException)
{
return 100;
}
catch (Exception ex)
{
Console.WriteLine("FAIL: Caught {0}", ex.GetType().Name);
}

return 101;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static void Test(int i)
{
GetAction()(100 / i);
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static Action<int> GetAction() => null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
<DebugType>None</DebugType>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>

0 comments on commit 3db5172

Please sign in to comment.