Skip to content

Commit bb66d72

Browse files
authored
JIT: fix AV caused by JIT (#120575)
The JIT attempts to deduce a class handle for the return type of TYP_REF calls, and almost always succeeds. However System.Array.Clone is special cased to return the type of its argument, and this argument may be a byref indir without a known managed type, so this deduction may fail. This causes the JIT to pass a null handle into the VM. Cope with this by setting the type instead of updating the type, if we discover it later via inlining. Closes #120522.
1 parent b28b882 commit bb66d72

File tree

4 files changed

+61
-9
lines changed

4 files changed

+61
-9
lines changed

src/coreclr/jit/fginline.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -701,20 +701,21 @@ class SubstitutePlaceholdersAndDevirtualizeWalker : public GenTreeVisitor<Substi
701701
// we may be able to sharpen the type for the local.
702702
if (tree->TypeIs(TYP_REF))
703703
{
704-
LclVarDsc* lcl = m_compiler->lvaGetDesc(lclNum);
704+
LclVarDsc* const lcl = m_compiler->lvaGetDesc(lclNum);
705705

706706
if (lcl->lvSingleDef)
707707
{
708-
bool isExact;
709-
bool isNonNull;
710-
CORINFO_CLASS_HANDLE newClass = m_compiler->gtGetClassHandle(value, &isExact, &isNonNull);
711-
712-
if (newClass != NO_CLASS_HANDLE)
708+
if (lcl->lvClassHnd == NO_CLASS_HANDLE)
709+
{
710+
m_compiler->lvaSetClass(lclNum, value);
711+
}
712+
else
713713
{
714-
m_compiler->lvaUpdateClass(lclNum, newClass, isExact);
715-
m_madeChanges = true;
716-
m_compiler->hasUpdatedTypeLocals = true;
714+
m_compiler->lvaUpdateClass(lclNum, value);
717715
}
716+
717+
m_madeChanges = true;
718+
m_compiler->hasUpdatedTypeLocals = true;
718719
}
719720
}
720721

src/coreclr/jit/importercalls.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6967,6 +6967,10 @@ class SpillRetExprHelper
69676967
{
69686968
comp->lvaSetClass(tmp, retClsHnd, isExact);
69696969
}
6970+
else
6971+
{
6972+
JITDUMP("Could not deduce class from [%06u]", comp->dspTreeID(retExpr));
6973+
}
69706974
}
69716975
}
69726976

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
using System.Threading;
7+
using Xunit;
8+
9+
public class Runtime_120522
10+
{
11+
static System.Collections.ArrayList array = [];
12+
13+
static void Problem(ref object[]? a)
14+
{
15+
a = new object[1];
16+
array.Add(a.Clone());
17+
}
18+
19+
[Fact]
20+
[MethodImpl(MethodImplOptions.NoOptimization)]
21+
public static int Test()
22+
{
23+
int i = 0;
24+
while (i < 200_000)
25+
{
26+
object[]? a = null;
27+
Problem(ref a);
28+
i++;
29+
30+
if (i % 10_000 == 0)
31+
{
32+
Thread.Sleep(200);
33+
}
34+
}
35+
36+
return i / 2000;
37+
}
38+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<DebugType>None</DebugType>
4+
<Optimize>True</Optimize>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="$(MSBuildProjectName).cs" />
8+
</ItemGroup>
9+
</Project>

0 commit comments

Comments
 (0)