Skip to content

Commit b2e41aa

Browse files
steveisokjkotas
authored andcommitted
Fix throwing exception when calling RunClassConstructor on a generic type with a static constructor (#105513)
* Fix throwing exception when calling RunClassConstructor on a generic type with a static constructor #99183 seems to have done away with assuming that a generic type's static constructor was always "initialized". As a result, if you call RunClassConstructor on it, the runtime would throw an exception. Fixes #103891 * Apply suggestions from code review --------- Co-authored-by: Jan Kotas <[email protected]>
1 parent e6cbc87 commit b2e41aa

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

src/coreclr/vm/methodtable.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3768,6 +3768,8 @@ void MethodTable::CheckRunClassInitThrowing()
37683768
if (IsSharedByGenericInstantiations())
37693769
return;
37703770

3771+
_ASSERTE(!ContainsGenericVariables());
3772+
37713773
EnsureStaticDataAllocated();
37723774
DoRunClassInitThrowing();
37733775
}

src/coreclr/vm/reflectioninvocation.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1306,7 +1306,8 @@ extern "C" void QCALLTYPE ReflectionInvocation_RunClassConstructor(QCall::TypeHa
13061306
return;
13071307

13081308
MethodTable *pMT = typeHnd.AsMethodTable();
1309-
if (pMT->IsClassInited())
1309+
// The ContainsGenericVariables check is to preserve back-compat where we assume the generic type is already initialized
1310+
if (pMT->IsClassInited() || pMT->ContainsGenericVariables())
13101311
return;
13111312

13121313
BEGIN_QCALL;

src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.IO;
77
using System.Reflection;
88
using System.Runtime.InteropServices;
9+
using System.Threading;
910
using Xunit;
1011

1112
namespace System.Runtime.CompilerServices.Tests
@@ -101,7 +102,8 @@ public static void RunClassConstructor()
101102
RuntimeTypeHandle t = typeof(HasCctor).TypeHandle;
102103
RuntimeHelpers.RunClassConstructor(t);
103104
Assert.Equal("Hello", HasCctorReceiver.S);
104-
return;
105+
// Should not throw
106+
RuntimeHelpers.RunClassConstructor(typeof(GenericHasCctor<>).TypeHandle);
105107
}
106108

107109
internal class HasCctor
@@ -117,6 +119,14 @@ internal class HasCctorReceiver
117119
public static string S;
118120
}
119121

122+
internal class GenericHasCctor<T>
123+
{
124+
static GenericHasCctor()
125+
{
126+
Thread.Yield(); // Make sure the preinitialization optimization doesn't eat this.
127+
}
128+
}
129+
120130
[Fact]
121131
public static void PrepareMethod()
122132
{

0 commit comments

Comments
 (0)