Skip to content

Commit

Permalink
[Mono] Fix function pointer check (#80855)
Browse files Browse the repository at this point in the history
* Fix function pointer check

* Make is_monomorphic_array return false when the element is function pointer

* Move test to a better location
  • Loading branch information
fanyang-mono authored Jan 23, 2023
1 parent 0ca3647 commit d6c2b43
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 5 deletions.
10 changes: 5 additions & 5 deletions src/mono/mono/metadata/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -4242,11 +4242,11 @@ mono_class_is_assignable_from_general (MonoClass *klass, MonoClass *oklass, gboo
}

if (m_class_get_byval_arg (klass)->type == MONO_TYPE_FNPTR) {
/*
* if both klass and oklass are fnptr, and they're equal, we would have returned at the
* beginning.
*/
/* Is this right? or do we need to look at signature compatibility? */
if (mono_metadata_signature_equal (klass_byval_arg->data.method, oklass_byval_arg->data.method)) {
*result = TRUE;
return;
}

*result = FALSE;
return;
}
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/metadata/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -4693,6 +4693,8 @@ is_monomorphic_array (MonoClass *klass)
return FALSE;

element_class = m_class_get_element_class (klass);
if (m_class_get_byval_arg (element_class)->type == MONO_TYPE_FNPTR)
return FALSE;
return mono_class_is_sealed (element_class) || m_class_is_valuetype (element_class);
}

Expand Down
46 changes: 46 additions & 0 deletions src/tests/Loader/classloader/Casting/Functionpointer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Runtime.InteropServices;

namespace TestFunctionPointer
{
unsafe class TestThings
{
public static delegate* managed<int>[][] Functions = {
new delegate* managed<int>[]
{
&Function,
},
};

public static int Function() => 100;

public static delegate* unmanaged<int>[][] Functions1 = {
new delegate* unmanaged<int>[]
{
&Function1,
},
};

[UnmanagedCallersOnly]
public static int Function1() => 100;

public static delegate* managed<int, int>[][] Functions2 = {
new delegate* managed<int, int>[]
{
&Function2,
},
};

public static int Function2(int a) {
return a;
}
}

unsafe class Program
{
public static int Main()
{
return TestThings.Functions2[0][0](TestThings.Functions[0][0]());
}
}
}
9 changes: 9 additions & 0 deletions src/tests/Loader/classloader/Casting/Functionpointer.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Include="Functionpointer.cs" />
</ItemGroup>
</Project>

0 comments on commit d6c2b43

Please # to comment.