diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 628b8c6f6e45dc..8fa55e0db9a511 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -2011,10 +2011,9 @@ PCODE MethodDesc::TryGetMultiCallableAddrOfCode(CORINFO_ACCESS_FLAGS accessFlags } CONTRACTL_END - if (IsGenericMethodDefinition()) + if (ContainsGenericVariables()) { - _ASSERTE(!"Cannot take the address of an uninstantiated generic method."); - COMPlusThrow(kInvalidProgramException); + COMPlusThrow(kInvalidOperationException, IDS_EE_CODEEXECUTION_CONTAINSGENERICVAR); } if (accessFlags & CORINFO_ACCESS_LDFTN) diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/MethodInfoTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/MethodInfoTests.cs index c0f95b43425565..5e791cc2d6dd0d 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/MethodInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/MethodInfoTests.cs @@ -306,6 +306,39 @@ public void InvokeUninstantiatedGenericMethod() Assert.Throws(() => GetMethod(typeof(MI_SubClass), nameof(MI_SubClass.StaticGenericMethod)).Invoke(null, [null])); } + [Fact] + public void InvokeUninstantiatedGenericType_GenericMethod() + { + Assert.Throws(() => GetMethod(typeof(MI_GenericClass<>), "GenericMethod4").Invoke(null, [null])); + } + + [Fact] + public void InvokeUninstantiatedGenericType_NonGenericMethod() + { + Assert.Throws(() => GetMethod(typeof(MI_GenericClass<>), "NonGenericMethod").Invoke(null, [null])); + } + + [Fact] + public void GetFunctionPointerFromUninstantiatedGenericMethod() + { + RuntimeMethodHandle handle = typeof(MI_SubClass).GetMethod(nameof(MI_SubClass.StaticGenericMethod))!.MethodHandle; + Assert.Throws(() => handle.GetFunctionPointer()); + } + + [Fact] + public void GetFunctionPointerOnUninstantiatedGenericType_GenericMethod() + { + RuntimeMethodHandle handle = typeof(MI_GenericClass<>).GetMethod("GenericMethod4")!.MethodHandle; + Assert.Throws(() => handle.GetFunctionPointer()); + } + + [Fact] + public void GetFunctionPointerOnUninstantiatedGenericType_NonGenericMethod() + { + RuntimeMethodHandle handle = typeof(MI_GenericClass<>).GetMethod("NonGenericMethod")!.MethodHandle; + Assert.Throws(() => handle.GetFunctionPointer()); + } + [Fact] public void GetHashCodeTest() { @@ -799,6 +832,8 @@ public class MI_GenericClass public T GenericMethod1(T t) => t; public T GenericMethod2(S s1, T t, string s2) => t; public static S GenericMethod3(S s) => s; + public static T GenericMethod4(T s) => s; + public static void NonGenericMethod() { } } public interface MethodInfoBaseDefinitionInterface diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 3728c995e9dd96..ef2d39632b6691 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -7474,6 +7474,11 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK; MonoMethod *local_cmethod = LOCAL_VAR (ip [2], MonoMethod*); + if (local_cmethod->is_generic || mono_class_is_gtd (local_cmethod->klass)) { + MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidOperationException", ""); + THROW_EX (ex, ip); + } + // FIXME push/pop LMF if (G_UNLIKELY (mono_method_has_unmanaged_callers_only_attribute (local_cmethod))) { local_cmethod = mono_marshal_get_managed_wrapper (local_cmethod, NULL, (MonoGCHandle)0, error); diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 240aa1f8a9b8bc..7bfa6bb3e69311 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -2938,6 +2938,11 @@ mono_jit_compile_method_jit_only (MonoMethod *method, MonoError *error) static gpointer get_ftnptr_for_method (MonoMethod *method, gboolean need_unbox, MonoError *error) { + if (method->is_generic || mono_class_is_gtd (method->klass)) { + mono_error_set_generic_error (error, "System", "InvalidOperationException", ""); + return NULL; + } + if (!mono_llvm_only) { gpointer res = mono_jit_compile_method (method, error); res = mini_add_method_trampoline (method, res, mono_method_needs_static_rgctx_invoke (method, TRUE), need_unbox);