diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 9209b3cc56ce7..a8f6bd04b8dbb 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -3768,6 +3768,8 @@ void MethodTable::CheckRunClassInitThrowing() if (IsSharedByGenericInstantiations()) return; + _ASSERTE(!ContainsGenericVariables()); + EnsureStaticDataAllocated(); DoRunClassInitThrowing(); } diff --git a/src/coreclr/vm/reflectioninvocation.cpp b/src/coreclr/vm/reflectioninvocation.cpp index aec38501adf60..eeef84d45df0e 100644 --- a/src/coreclr/vm/reflectioninvocation.cpp +++ b/src/coreclr/vm/reflectioninvocation.cpp @@ -1306,7 +1306,8 @@ extern "C" void QCALLTYPE ReflectionInvocation_RunClassConstructor(QCall::TypeHa return; MethodTable *pMT = typeHnd.AsMethodTable(); - if (pMT->IsClassInited()) + // The ContainsGenericVariables check is to preserve back-compat where we assume the generic type is already initialized + if (pMT->IsClassInited() || pMT->ContainsGenericVariables()) return; BEGIN_QCALL; diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs index 2fd5267409cb6..13ce28e4f233c 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs @@ -6,6 +6,7 @@ using System.IO; using System.Reflection; using System.Runtime.InteropServices; +using System.Threading; using Xunit; namespace System.Runtime.CompilerServices.Tests @@ -101,7 +102,8 @@ public static void RunClassConstructor() RuntimeTypeHandle t = typeof(HasCctor).TypeHandle; RuntimeHelpers.RunClassConstructor(t); Assert.Equal("Hello", HasCctorReceiver.S); - return; + // Should not throw + RuntimeHelpers.RunClassConstructor(typeof(GenericHasCctor<>).TypeHandle); } internal class HasCctor @@ -117,6 +119,14 @@ internal class HasCctorReceiver public static string S; } + internal class GenericHasCctor + { + static GenericHasCctor() + { + Thread.Yield(); // Make sure the preinitialization optimization doesn't eat this. + } + } + [Fact] public static void PrepareMethod() {