diff --git a/src/mono/mono/metadata/class.c b/src/mono/mono/metadata/class.c index 834cf8688cd3e..abd0948e3a2f5 100644 --- a/src/mono/mono/metadata/class.c +++ b/src/mono/mono/metadata/class.c @@ -870,6 +870,31 @@ inflate_generic_type (MonoImage *image, MonoType *type, MonoGenericContext *cont nt->data.type = inflated; return nt; } + case MONO_TYPE_FNPTR: { + MonoMethodSignature *in_sig = type->data.method; + // quick bail out - if there are no type variables anywhere in the signature, + // there's nothing that could get inflated. + if (!in_sig->has_type_parameters) { + if (!changed) + return NULL; + else + return type; + } + MonoMethodSignature *new_sig = mono_inflate_generic_signature (in_sig, context, error); + if ((!new_sig && !changed) || !is_ok (error)) { + return NULL; + } else if (!new_sig && changed) + return type; + if (new_sig == in_sig) { + if (!changed) + return NULL; + else + return type; + } + MonoType *nt = mono_metadata_type_dup (image, type); + nt->data.method = new_sig; + return nt; + } default: if (!changed) return NULL; diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 5e8fcc4dfd408..d0e0b2327907c 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3963,7 +3963,7 @@ mono_marshal_get_native_func_wrapper_indirect (MonoClass *caller_class, MonoMeth return res; char *name = mono_signature_to_name (sig, "wrapper_native_indirect"); - MonoMethodBuilder *mb = mono_mb_new (caller_class, name, MONO_WRAPPER_MANAGED_TO_NATIVE); + MonoMethodBuilder *mb = mono_mb_new (get_wrapper_target_class (image), name, MONO_WRAPPER_MANAGED_TO_NATIVE); mb->method->save_lmf = 1; WrapperInfo *info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NATIVE_FUNC_INDIRECT); diff --git a/src/tests/Interop/MarshalAPI/FunctionPointer/GenericFunctionPointer.cs b/src/tests/Interop/MarshalAPI/FunctionPointer/GenericFunctionPointer.cs index 14021dae9550e..9bc6d4b05fd6e 100644 --- a/src/tests/Interop/MarshalAPI/FunctionPointer/GenericFunctionPointer.cs +++ b/src/tests/Interop/MarshalAPI/FunctionPointer/GenericFunctionPointer.cs @@ -50,6 +50,11 @@ internal static unsafe void NonGenericCalli(void* fnptr, ref int val, float a { ((delegate* unmanaged)fnptr)(ref val, arg); } + + internal static unsafe int NonGenericCalliInNonGenericMethod(void* fnptr, float arg) + { + return ((delegate* unmanaged)fnptr)(arg); + } } struct BlittableGeneric @@ -99,6 +104,12 @@ public static void RunGenericFunctionPointerTest(float inVal) GenericCaller.NonGenericCalli((delegate* unmanaged)&UnmanagedExportedFunctionRefInt, ref outVar, inVal); } Assert.Equal(expectedValue, outVar); + + unsafe + { + outVar = GenericCaller.NonGenericCalliInNonGenericMethod((delegate* unmanaged)&UnmanagedExportedFunction, inVal); + } + Assert.Equal(expectedValue, outVar); } [ConditionalFact(nameof(CanRunInvalidGenericFunctionPointerTest))]