diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs index 998094377be4f4..ccaba707130386 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs @@ -1599,7 +1599,6 @@ public static void Copy_SourceAndDestinationNeverConvertible_ThrowsArrayTypeMism } [Fact] - [SkipOnMono("https://github.com/dotnet/runtime/issues/104197")] public static unsafe void Copy_CompatiblePointers() { // Can copy between compatible pointers diff --git a/src/mono/mono/metadata/class.c b/src/mono/mono/metadata/class.c index 043338c14899d9..2117c94c06a840 100644 --- a/src/mono/mono/metadata/class.c +++ b/src/mono/mono/metadata/class.c @@ -3582,6 +3582,7 @@ mono_class_is_subclass_of_internal (MonoClass *klass, MonoClass *klassc, gboolean check_interfaces) { MONO_REQ_GC_UNSAFE_MODE; + /* FIXME test for interfaces with variant generic arguments */ if (check_interfaces) { mono_class_init_internal (klass); @@ -4284,13 +4285,9 @@ mono_class_is_assignable_from_general (MonoClass *klass, MonoClass *oklass, gboo MonoClass *eclass; MonoClass *eoclass; - if (signature_assignment) { - eclass = composite_type_to_reduced_element_type (klass); - eoclass = composite_type_to_reduced_element_type (oklass); - } else { - eclass = m_class_get_cast_class (klass); - eoclass = m_class_get_cast_class (oklass); - } + + eclass = composite_type_to_reduced_element_type (klass); + eoclass = composite_type_to_reduced_element_type (oklass); *result = (eclass == eoclass); return; diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 67cd6470df19db..43f3d32653f321 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -199,12 +199,7 @@ ves_icall_System_Array_GetValueImpl (MonoObjectHandleOnStack array_handle, MonoO MonoClass * const array_class = mono_object_class (array); MonoClass * const element_class = m_class_get_element_class (array_class); - if (m_class_is_native_pointer (element_class)) { - mono_error_set_not_supported (error, NULL); - return; - } - - if (m_class_is_valuetype (element_class)) { + if (m_class_is_valuetype (element_class) || mono_class_is_pointer (element_class)) { gsize element_size = mono_array_element_size (array_class); gpointer element_address = mono_array_addr_with_size_fast (array, element_size, (gsize)pos); MonoObject *res = mono_value_box_checked (element_class, element_address, error); @@ -872,13 +867,16 @@ ves_icall_System_Array_FastCopy (MonoObjectHandleOnStack source_handle, int sour if (m_class_is_valuetype (dest_class) || m_class_is_enumtype (dest_class) || m_class_is_valuetype (src_class) || m_class_is_valuetype (src_class)) return FALSE; - - /* It's only safe to copy between arrays if we can ensure the source will always have a subtype of the destination. We bail otherwise. */ - if (!mono_class_is_subclass_of_internal (src_class, dest_class, FALSE)) - return FALSE; - - if (m_class_is_native_pointer (src_class) || m_class_is_native_pointer (dest_class)) - return FALSE; + + if (mono_class_is_pointer (dest_class) || mono_class_is_pointer (src_class)) { + /* if we're copying between at least one array of pointers, only allow it if both dest_class is assignable from src_class (checked above, and src_class is assignable from dest_class). This should only be true if both src_class and dest_class have a common cast_class. (for example: int*[] and uint*[] are ok, but void*[] and int*[] are not)). */ + if (!mono_class_is_assignable_from_internal (dest_class, src_class)) + return FALSE; + } else { + /* It's only safe to copy between arrays if we can ensure the source will always have a subtype of the destination. We bail otherwise. */ + if (!mono_class_is_subclass_of_internal (src_class, dest_class, FALSE)) + return FALSE; + } } if (m_class_is_valuetype (dest_class)) { diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index 2a0e9e9834e094..1c1a632a4003e7 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -6529,7 +6529,7 @@ mono_value_box_handle (MonoClass *klass, gpointer value, MonoError *error) error_init (error); - g_assert (m_class_is_valuetype (klass)); + g_assert (m_class_is_valuetype (klass) || mono_class_is_pointer (klass)); g_assert (value != NULL); if (G_UNLIKELY (m_class_is_byreflike (klass))) { char *full_name = mono_type_get_full_name (klass);