Skip to content

Commit 51a7310

Browse files
Add a test
Without the fix, 4 out of 5 runs fail on my machine.
1 parent bfa03b2 commit 51a7310

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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.Threading;
6+
using System.Runtime.InteropServices;
7+
using System.Runtime.CompilerServices;
8+
9+
unsafe class ExposedLocalsNumbering
10+
{
11+
private static volatile bool s_mutateIndex;
12+
private static volatile bool s_finished;
13+
private static int* s_pIndex = (int*)NativeMemory.Alloc(4);
14+
15+
public static int Main()
16+
{
17+
const int RetryCount = 100;
18+
const int UnsafeIndex = 1;
19+
20+
new Thread(_ =>
21+
{
22+
while (!s_finished)
23+
{
24+
if (s_mutateIndex)
25+
{
26+
*s_pIndex = UnsafeIndex;
27+
}
28+
}
29+
}).Start();
30+
31+
int[] array = new int[UnsafeIndex + 1];
32+
array[UnsafeIndex] = 1;
33+
34+
int safeIndex = 0;
35+
for (int i = 0; i < RetryCount; i++)
36+
{
37+
try
38+
{
39+
if (RunBoundsChecks(array.AsSpan(0, UnsafeIndex), &safeIndex) != 0)
40+
{
41+
s_finished = true;
42+
return 101;
43+
}
44+
}
45+
catch (IndexOutOfRangeException) { }
46+
}
47+
48+
s_finished = true;
49+
return 100;
50+
}
51+
52+
[MethodImpl(MethodImplOptions.NoInlining)]
53+
private static int RunBoundsChecks(Span<int> span, int* pSafeIndex)
54+
{
55+
int result = 0;
56+
int index = 0;
57+
CaptureIndex(&index);
58+
59+
result += span[index];
60+
result += span[index];
61+
result += span[index];
62+
result += span[index];
63+
64+
result += span[index];
65+
result += span[index];
66+
result += span[index];
67+
result += span[index];
68+
69+
result += span[index];
70+
result += span[index];
71+
result += span[index];
72+
result += span[index];
73+
74+
s_pIndex = pSafeIndex;
75+
s_mutateIndex = false;
76+
77+
return result;
78+
}
79+
80+
[MethodImpl(MethodImplOptions.NoInlining)]
81+
private static void CaptureIndex(int* pIndex)
82+
{
83+
s_pIndex = pIndex;
84+
s_mutateIndex = true;
85+
}
86+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<DebugType>None</DebugType>
5+
<Optimize>True</Optimize>
6+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
7+
</PropertyGroup>
8+
<ItemGroup>
9+
<Compile Include="$(MSBuildProjectName).cs" />
10+
<CLRTestEnvironmentVariable Include="DOTNET_JitNoCSE" Value="1" />
11+
</ItemGroup>
12+
</Project>

0 commit comments

Comments
 (0)