From b4e565f21b5dda3ecd3513986eb2eb15d184559b Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Thu, 9 May 2019 15:36:44 +0300 Subject: [PATCH] [netcore] Set of workarounds for ArrayTests (#14369) * Fix ushort to char conversion * fix one more test * Enable more Array tests * fix comment * Fix CreateInstance_NotSupportedType_ThrowsNotSupportedException * Address feedback * Update ArraySortHelper.cs * fix compilation error? * bump corefx-tests, fix one more array.copy issue --- .../System.Collections.Generic/ArraySortHelper.cs | 2 ++ .../System.Collections.Generic/Comparer.cs | 2 ++ .../System.Collections.Generic/EqualityComparer.cs | 2 ++ mcs/class/System.Private.CoreLib/System/Array.cs | 14 ++++++++-- mono/metadata/icall.c | 32 ++++++++++++++++------ netcore/Makefile | 8 +++--- netcore/excludes-System.Runtime.Tests.rsp | 14 ---------- 7 files changed, 44 insertions(+), 30 deletions(-) diff --git a/mcs/class/System.Private.CoreLib/System.Collections.Generic/ArraySortHelper.cs b/mcs/class/System.Private.CoreLib/System.Collections.Generic/ArraySortHelper.cs index 71a0403c43e..985308eea66 100644 --- a/mcs/class/System.Private.CoreLib/System.Collections.Generic/ArraySortHelper.cs +++ b/mcs/class/System.Private.CoreLib/System.Collections.Generic/ArraySortHelper.cs @@ -1,3 +1,5 @@ +#nullable enable + namespace System.Collections.Generic { partial class ArraySortHelper diff --git a/mcs/class/System.Private.CoreLib/System.Collections.Generic/Comparer.cs b/mcs/class/System.Private.CoreLib/System.Collections.Generic/Comparer.cs index 2b99bad803d..2ae72877f2e 100644 --- a/mcs/class/System.Private.CoreLib/System.Collections.Generic/Comparer.cs +++ b/mcs/class/System.Private.CoreLib/System.Collections.Generic/Comparer.cs @@ -1,3 +1,5 @@ +#nullable enable + using System.Runtime.CompilerServices; namespace System.Collections.Generic diff --git a/mcs/class/System.Private.CoreLib/System.Collections.Generic/EqualityComparer.cs b/mcs/class/System.Private.CoreLib/System.Collections.Generic/EqualityComparer.cs index 99353a53476..53dddbcd9a4 100644 --- a/mcs/class/System.Private.CoreLib/System.Collections.Generic/EqualityComparer.cs +++ b/mcs/class/System.Private.CoreLib/System.Collections.Generic/EqualityComparer.cs @@ -1,3 +1,5 @@ +#nullable enable + using System.Runtime.CompilerServices; namespace System.Collections.Generic diff --git a/mcs/class/System.Private.CoreLib/System/Array.cs b/mcs/class/System.Private.CoreLib/System/Array.cs index b1fdd960082..96b366e151f 100644 --- a/mcs/class/System.Private.CoreLib/System/Array.cs +++ b/mcs/class/System.Private.CoreLib/System/Array.cs @@ -3,7 +3,6 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Reflection; namespace System { @@ -129,7 +128,7 @@ namespace System Type src_type = sourceArray.GetType ().GetElementType (); Type dst_type = destinationArray.GetType ().GetElementType (); - var dst_type_vt = dst_type.IsValueType; + var dst_type_vt = dst_type.IsValueType && Nullable.GetUnderlyingType(dst_type) == null; if (src_type.IsEnum) src_type = Enum.GetUnderlyingType (src_type); @@ -150,7 +149,7 @@ namespace System for (int i = 0; i < length; i++) { Object srcval = sourceArray.GetValueImpl (source_pos + i); - if (srcval == null && dst_type_vt) + if (dst_type_vt && (srcval == null || (src_type == typeof (object) && srcval.GetType () != dst_type))) throw new InvalidCastException (); try { @@ -197,6 +196,11 @@ namespace System } else if (source.IsPointer && target.IsPointer) { return true; } else if (source.IsPrimitive && target.IsPrimitive) { + + // Special case: normally C# doesn't allow implicit ushort->char cast). + if (source == typeof (ushort) && target == typeof (char)) + return true; + // Allow primitive type widening return DefaultBinder.CanChangePrimitive (source, target); } else if (!source.IsValueType && !source.IsPointer) { @@ -269,6 +273,8 @@ namespace System throw new NotSupportedException ("Array type can not be void"); if (elementType.ContainsGenericParameters) throw new NotSupportedException ("Array type can not be an open generic type"); + if (elementType.IsByRef) + throw new NotSupportedException (SR.NotSupported_Type); return CreateInstanceImpl (elementType, lengths, bounds); } @@ -289,6 +295,8 @@ namespace System throw new NotSupportedException ("Array type can not be void"); if (elementType.ContainsGenericParameters) throw new NotSupportedException ("Array type can not be an open generic type"); + if (elementType.IsByRef) + throw new NotSupportedException (SR.NotSupported_Type); if (lengths.Length < 1) throw new ArgumentException ("Arrays must contain >= 1 elements."); diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index d08aaf42e96..7f15220d271 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -154,7 +154,7 @@ icallarray_print (const char *format, ...) static GENERATE_GET_CLASS_WITH_CACHE (module, "System.Reflection", "Module") static void -array_set_value_impl (MonoArrayHandle arr, MonoObjectHandle value, guint32 pos, MonoError *error); +array_set_value_impl (MonoArrayHandle arr, MonoObjectHandle value, guint32 pos, gboolean strict, MonoError *error); static MonoArrayHandle type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error); @@ -252,7 +252,7 @@ ves_icall_System_Array_GetValue (MonoArrayHandle arr, MonoArrayHandle indices, M void ves_icall_System_Array_SetValueImpl (MonoArrayHandle arr, MonoObjectHandle value, guint32 pos, MonoError *error) { - array_set_value_impl (arr, value, pos, error); + array_set_value_impl (arr, value, pos, FALSE, error); } static inline void @@ -263,7 +263,7 @@ set_invalid_cast (MonoError *error, MonoClass *src_class, MonoClass *dst_class) } static void -array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, guint32 pos, MonoError *error) +array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, guint32 pos, gboolean strict, MonoError *error) { MonoClass *ac, *vc, *ec; gint32 esize, vsize; @@ -273,6 +273,8 @@ array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, gint64 i64 = 0; gdouble r64 = 0; gboolean castOk = FALSE; + gboolean et_isenum = FALSE; + gboolean vt_isenum = FALSE; error_init (error); @@ -312,18 +314,20 @@ array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, #ifdef ENABLE_NETCORE #define WIDENING_MSG NULL +#define WIDENING_ARG NULL #else #define WIDENING_MSG "not a widening conversion" +#define WIDENING_ARG "value" #endif #define NO_WIDENING_CONVERSION G_STMT_START{ \ - mono_error_set_argument (error, "value", WIDENING_MSG); \ + mono_error_set_argument (error, WIDENING_ARG, WIDENING_MSG); \ break; \ }G_STMT_END #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{ \ if (esize < vsize + (extra)) { \ - mono_error_set_argument (error, "value", WIDENING_MSG); \ + mono_error_set_argument (error, WIDENING_ARG, WIDENING_MSG); \ break; \ } \ }G_STMT_END @@ -409,10 +413,20 @@ array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, vsize = mono_class_value_size (vc, NULL); - if (et == MONO_TYPE_VALUETYPE && m_class_is_enumtype (m_class_get_byval_arg (ec)->data.klass)) + et_isenum = et == MONO_TYPE_VALUETYPE && m_class_is_enumtype (m_class_get_byval_arg (ec)->data.klass); + vt_isenum = vt == MONO_TYPE_VALUETYPE && m_class_is_enumtype (m_class_get_byval_arg (vc)->data.klass); + +#if ENABLE_NETCORE + if (strict && et_isenum && !vt_isenum) { + INVALID_CAST; + goto leave; + } +#endif + + if (et_isenum) et = mono_class_enum_basetype_internal (m_class_get_byval_arg (ec)->data.klass)->type; - if (vt == MONO_TYPE_VALUETYPE && m_class_is_enumtype (m_class_get_byval_arg (vc)->data.klass)) + if (vt_isenum) vt = mono_class_enum_basetype_internal (m_class_get_byval_arg (vc)->data.klass)->type; #define ASSIGN_UNSIGNED(etype) G_STMT_START{\ @@ -657,7 +671,7 @@ ves_icall_System_Array_SetValue (MonoArrayHandle arr, MonoObjectHandle value, return; } - array_set_value_impl (arr, value, idx, error); + array_set_value_impl (arr, value, idx, TRUE, error); return; } @@ -681,7 +695,7 @@ ves_icall_System_Array_SetValue (MonoArrayHandle arr, MonoObjectHandle value, pos = pos * dim.length + idx - dim.lower_bound; } - array_set_value_impl (arr, value, pos, error); + array_set_value_impl (arr, value, pos, TRUE, error); } MonoArrayHandle diff --git a/netcore/Makefile b/netcore/Makefile index 4fc34bf6fd1..b550f038e1d 100644 --- a/netcore/Makefile +++ b/netcore/Makefile @@ -5,7 +5,7 @@ include ../mcs/build/config.make # # Extracted MicrosoftPrivateCoreFxNETCoreAppVersion from https://github.com/dotnet/coreclr/blob/master/eng/Versions.props#L12 -NETCORETESTS_VERSION := 4.6.0-preview6.19229.1 +NETCORETESTS_VERSION := 4.6.0-preview6.19257.4 # Extracted MicrosoftNETCoreAppVersion from https://github.com/dotnet/coreclr/blob/master/eng/Versions.props#L14 NETCOREAPP_VERSION := 3.0.0-preview5-27620-01 @@ -72,9 +72,9 @@ corefx/.stamp-dl-corefx-tests-$(NETCORETESTS_VERSION): python dl-test-assets.py corefx-test-assets.xml $(FEED_BASE_URL) corefx/tests touch $@ -run-sample: +run-sample: prepare dotnet build sample/HelloWorld - COMPlus_DebugWriteToStdErr=1 ./dotnet --fx-version "$(NETCOREAPP_VERSION)" sample/HelloWorld/bin/Debug/netcoreapp3.0/HelloWorld.dll + MONO_ENV_OPTIONS="--debug" COMPlus_DebugWriteToStdErr=1 ./dotnet --fx-version "$(NETCOREAPP_VERSION)" sample/HelloWorld/bin/Debug/netcoreapp3.0/HelloWorld.dll run-aspnet-sample: prepare rm -rf sample/AspNetCore/{bin,obj} @@ -89,7 +89,7 @@ SHAREDRUNTIME := shared/Microsoft.NETCore.App/$(NETCOREAPP_VERSION) bcl: $(MAKE) -C ../mcs/build/ common/Consts.cs $(MAKE) -C ../mcs/class/System.Private.CoreLib - cp ../mcs/class/System.Private.CoreLib/bin/$(COREARCH)/System.Private.CoreLib.dll $(SHAREDRUNTIME) + cp ../mcs/class/System.Private.CoreLib/bin/$(COREARCH)/System.Private.CoreLib.{dll,pdb} $(SHAREDRUNTIME) runtime: $(MAKE) -C ../mono diff --git a/netcore/excludes-System.Runtime.Tests.rsp b/netcore/excludes-System.Runtime.Tests.rsp index e96e54a3dcf..f4d3d75b9bf 100644 --- a/netcore/excludes-System.Runtime.Tests.rsp +++ b/netcore/excludes-System.Runtime.Tests.rsp @@ -40,26 +40,12 @@ # while the test passes, xunit fails in the end if it's enabled -nomethod System.Tests.Types.VoidTests.IsByRef_Get_ReturnsExpected -# Implement more checks in Array.Copy --nomethod System.Tests.ArrayTests.SetValue_Casting_Invalid --nomethod System.Tests.ArrayTests.Copy_SZArray --nomethod System.Tests.ArrayTests.CreateInstance_NotSupportedType_ThrowsNotSupportedException --nomethod System.Tests.ActivatorTests.CreateInstance_PrimitiveWidening_ThrowsInvalidCastException - # Boxed pointers are not supported? https://github.com/mono/mono/blob/ced517784b2a07fb851e2227dac04e0df2262d57/mcs/class/corlib/ReferenceSources/RuntimeType.cs#L229 -nomethod System.Reflection.Tests.InvokeRefReturnNetcoreTests.TestByRefLikeRefReturn # `private new T Foo` doesn't hide members from Type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) -nomethod System.Reflection.Tests.TypeTests_HiddenTestingOrder.HideDetectionHappensBeforeBindingFlagChecks -# remove once CoreFX gets https://github.com/dotnet/coreclr/pull/24279 --nomethod System.Tests.TimeSpanTests.FromMilliseconds --nomethod System.Tests.TimeSpanTests.FromMilliseconds_Invalid --nomethod System.Tests.TimeSpanTests.Multiplication --nomethod System.Tests.TimeSpanTests.NamedMultiplication --nomethod System.Tests.TimeSpanTests.Division --nomethod System.Tests.TimeSpanTests.NamedDivision - # TODO: ignore in CoreFX for mono runtime: -nomethod System.Reflection.Tests.PointerTests.* -nomethod System.Tests.StringTests.NormalizationTest -- 2.11.4.GIT