Skip to content

Commit 9565550

Browse files
steveharterbuyaa-n
andauthored
Throw InvalidOperationException on RuntimeMethodHandle.GetFunctionPointer() for generic methods (#104644)
* Throw InvalidOperationException on RuntimeMethodHandle.GetFunctionPointer() for generic methods * Also check if owning type is generic; add checks to mono interpreter * Update src/coreclr/vm/method.cpp --------- Co-authored-by: Buyaa Namnan <[email protected]>
1 parent 5e7de53 commit 9565550

File tree

4 files changed

+47
-3
lines changed

4 files changed

+47
-3
lines changed

src/coreclr/vm/method.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,10 +2136,9 @@ PCODE MethodDesc::TryGetMultiCallableAddrOfCode(CORINFO_ACCESS_FLAGS accessFlags
21362136
}
21372137
CONTRACTL_END
21382138

2139-
if (IsGenericMethodDefinition())
2139+
if (ContainsGenericVariables())
21402140
{
2141-
_ASSERTE(!"Cannot take the address of an uninstantiated generic method.");
2142-
COMPlusThrow(kInvalidProgramException);
2141+
COMPlusThrow(kInvalidOperationException, IDS_EE_CODEEXECUTION_CONTAINSGENERICVAR);
21432142
}
21442143

21452144
if (accessFlags & CORINFO_ACCESS_LDFTN)

src/libraries/System.Runtime/tests/System.Reflection.Tests/MethodInfoTests.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,39 @@ public void InvokeUninstantiatedGenericMethod()
306306
Assert.Throws<InvalidOperationException>(() => GetMethod(typeof(MI_SubClass), nameof(MI_SubClass.StaticGenericMethod)).Invoke(null, [null]));
307307
}
308308

309+
[Fact]
310+
public void InvokeUninstantiatedGenericType_GenericMethod()
311+
{
312+
Assert.Throws<InvalidOperationException>(() => GetMethod(typeof(MI_GenericClass<>), "GenericMethod4").Invoke(null, [null]));
313+
}
314+
315+
[Fact]
316+
public void InvokeUninstantiatedGenericType_NonGenericMethod()
317+
{
318+
Assert.Throws<InvalidOperationException>(() => GetMethod(typeof(MI_GenericClass<>), "NonGenericMethod").Invoke(null, [null]));
319+
}
320+
321+
[Fact]
322+
public void GetFunctionPointerFromUninstantiatedGenericMethod()
323+
{
324+
RuntimeMethodHandle handle = typeof(MI_SubClass).GetMethod(nameof(MI_SubClass.StaticGenericMethod))!.MethodHandle;
325+
Assert.Throws<InvalidOperationException>(() => handle.GetFunctionPointer());
326+
}
327+
328+
[Fact]
329+
public void GetFunctionPointerOnUninstantiatedGenericType_GenericMethod()
330+
{
331+
RuntimeMethodHandle handle = typeof(MI_GenericClass<>).GetMethod("GenericMethod4")!.MethodHandle;
332+
Assert.Throws<InvalidOperationException>(() => handle.GetFunctionPointer());
333+
}
334+
335+
[Fact]
336+
public void GetFunctionPointerOnUninstantiatedGenericType_NonGenericMethod()
337+
{
338+
RuntimeMethodHandle handle = typeof(MI_GenericClass<>).GetMethod("NonGenericMethod")!.MethodHandle;
339+
Assert.Throws<InvalidOperationException>(() => handle.GetFunctionPointer());
340+
}
341+
309342
[Fact]
310343
public void GetHashCodeTest()
311344
{
@@ -799,6 +832,8 @@ public class MI_GenericClass<T>
799832
public T GenericMethod1(T t) => t;
800833
public T GenericMethod2<S>(S s1, T t, string s2) => t;
801834
public static S GenericMethod3<S>(S s) => s;
835+
public static T GenericMethod4(T s) => s;
836+
public static void NonGenericMethod() { }
802837
}
803838

804839
public interface MethodInfoBaseDefinitionInterface

src/mono/mono/mini/interp/interp.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7476,6 +7476,11 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
74767476

74777477
MonoMethod *local_cmethod = LOCAL_VAR (ip [2], MonoMethod*);
74787478

7479+
if (local_cmethod->is_generic || mono_class_is_gtd (local_cmethod->klass)) {
7480+
MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidOperationException", "");
7481+
THROW_EX (ex, ip);
7482+
}
7483+
74797484
// FIXME push/pop LMF
74807485
if (G_UNLIKELY (mono_method_has_unmanaged_callers_only_attribute (local_cmethod))) {
74817486
local_cmethod = mono_marshal_get_managed_wrapper (local_cmethod, NULL, (MonoGCHandle)0, error);

src/mono/mono/mini/mini-runtime.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2939,6 +2939,11 @@ mono_jit_compile_method_jit_only (MonoMethod *method, MonoError *error)
29392939
static gpointer
29402940
get_ftnptr_for_method (MonoMethod *method, gboolean need_unbox, MonoError *error)
29412941
{
2942+
if (method->is_generic || mono_class_is_gtd (method->klass)) {
2943+
mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
2944+
return NULL;
2945+
}
2946+
29422947
if (!mono_llvm_only) {
29432948
gpointer res = mono_jit_compile_method (method, error);
29442949
res = mini_add_method_trampoline (method, res, mono_method_needs_static_rgctx_invoke (method, TRUE), need_unbox);

0 commit comments

Comments
 (0)