From 8a0559f5bb8f1466df1b2b16a32264093c8a08b3 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Thu, 19 Jan 2023 07:52:40 -0800 Subject: [PATCH 1/3] Fix function pointer check --- src/mono/mono/metadata/class.c | 10 ++-- src/mono/mono/metadata/marshal.c | 2 +- .../functionpointer/Functionpointer.cs | 46 +++++++++++++++++++ .../functionpointer/Functionpointer.csproj | 9 ++++ 4 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.cs create mode 100644 src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.csproj diff --git a/src/mono/mono/metadata/class.c b/src/mono/mono/metadata/class.c index 3a04a9dee77c41..0491ce5f3a1cc7 100644 --- a/src/mono/mono/metadata/class.c +++ b/src/mono/mono/metadata/class.c @@ -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; } diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index bca051413a6a8d..ce2f09f8d97f02 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -4702,7 +4702,7 @@ get_virtual_stelemref_kind (MonoClass *element_class) if (element_class == mono_defaults.object_class) return STELEMREF_OBJECT; if (is_monomorphic_array (element_class)) - return STELEMREF_SEALED_CLASS; + return STELEMREF_COMPLEX; /* magic ifaces requires aditional checks for when the element type is an array */ if (MONO_CLASS_IS_INTERFACE_INTERNAL (element_class) && m_class_is_array_special_interface (element_class)) diff --git a/src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.cs b/src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.cs new file mode 100644 index 00000000000000..95d7bf33b1303c --- /dev/null +++ b/src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.cs @@ -0,0 +1,46 @@ +using System; +using System.Runtime.InteropServices; + +namespace TestFunctionPointer +{ + unsafe class TestThings + { + public static delegate* managed[][] Functions = { + new delegate* managed[] + { + &Function, + }, + }; + + public static int Function() => 100; + + public static delegate* unmanaged[][] Functions1 = { + new delegate* unmanaged[] + { + &Function1, + }, + }; + + [UnmanagedCallersOnly] + public static int Function1() => 100; + + public static delegate* managed[][] Functions2 = { + new delegate* managed[] + { + &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]()); + } + } +} \ No newline at end of file diff --git a/src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.csproj b/src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.csproj new file mode 100644 index 00000000000000..51f7075c49c815 --- /dev/null +++ b/src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.csproj @@ -0,0 +1,9 @@ + + + Exe + true + + + + + \ No newline at end of file From 8ae248eabd3d3071356be1f2ea3ba1ead84407b9 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Thu, 19 Jan 2023 10:58:53 -0800 Subject: [PATCH 2/3] Make is_monomorphic_array return false when the element is function pointer --- src/mono/mono/metadata/marshal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index ce2f09f8d97f02..5ab899e032d0eb 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -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); } @@ -4702,7 +4704,7 @@ get_virtual_stelemref_kind (MonoClass *element_class) if (element_class == mono_defaults.object_class) return STELEMREF_OBJECT; if (is_monomorphic_array (element_class)) - return STELEMREF_COMPLEX; + return STELEMREF_SEALED_CLASS; /* magic ifaces requires aditional checks for when the element type is an array */ if (MONO_CLASS_IS_INTERFACE_INTERNAL (element_class) && m_class_is_array_special_interface (element_class)) From 898f68ed08b40b3b11e402eb5b79432cc5f38372 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Thu, 19 Jan 2023 11:36:09 -0800 Subject: [PATCH 3/3] Move test to a better location --- .../classloader/Casting}/Functionpointer.cs | 0 .../classloader/Casting}/Functionpointer.csproj | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/tests/{baseservices/typeequivalence/functionpointer => Loader/classloader/Casting}/Functionpointer.cs (100%) rename src/tests/{baseservices/typeequivalence/functionpointer => Loader/classloader/Casting}/Functionpointer.csproj (100%) diff --git a/src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.cs b/src/tests/Loader/classloader/Casting/Functionpointer.cs similarity index 100% rename from src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.cs rename to src/tests/Loader/classloader/Casting/Functionpointer.cs diff --git a/src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.csproj b/src/tests/Loader/classloader/Casting/Functionpointer.csproj similarity index 100% rename from src/tests/baseservices/typeequivalence/functionpointer/Functionpointer.csproj rename to src/tests/Loader/classloader/Casting/Functionpointer.csproj