From a33ea98572b93ad1b357961e2b2904605cdec9f6 Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 4 Aug 2021 00:16:26 +0200 Subject: [PATCH 1/9] STJ: Fix deserialization of UInt16 properties (#56793) Fix #56792 --- .../gen/JsonSourceGenerator.Parser.cs | 2 +- .../ContextClasses.cs | 1 + .../MetadataAndSerializationContextTests.cs | 2 + .../MetadataContextTests.cs | 4 ++ .../MixedModeContextTests.cs | 2 + .../RealWorldContextTests.cs | 44 +++++++++++++++++++ .../SerializationContextTests.cs | 18 ++++++++ .../TestClasses.cs | 15 +++++++ 8 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index 2290738c51aa3..184a1774c29cd 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -1051,7 +1051,7 @@ private void PopulateNumberTypes() _numberTypes.Add(ResolveType(SpecialType.System_Int32)); _numberTypes.Add(ResolveType(SpecialType.System_Int64)); _numberTypes.Add(ResolveType(SpecialType.System_Single)); - _numberTypes.Add(ResolveType(SpecialType.System_UInt64)); + _numberTypes.Add(ResolveType(SpecialType.System_UInt16)); _numberTypes.Add(ResolveType(SpecialType.System_UInt32)); _numberTypes.Add(ResolveType(SpecialType.System_UInt64)); } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs index c4ade896e1d64..9eaf4a4beab28 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs @@ -10,6 +10,7 @@ namespace System.Text.Json.SourceGeneration.Tests public interface ITestContext { public JsonTypeInfo Location { get; } + public JsonTypeInfo NumberTypes { get; } public JsonTypeInfo RepeatedLocation { get; } public JsonTypeInfo ActiveOrUpcomingEvent { get; } public JsonTypeInfo CampaignSummaryViewModel { get; } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs index 94f77f5bc0cd4..c924e5af8ccf3 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs @@ -8,6 +8,7 @@ namespace System.Text.Json.SourceGeneration.Tests { [JsonSerializable(typeof(Location))] [JsonSerializable(typeof(RepeatedTypes.Location), TypeInfoPropertyName = "RepeatedLocation")] + [JsonSerializable(typeof(NumberTypes))] [JsonSerializable(typeof(ActiveOrUpcomingEvent))] [JsonSerializable(typeof(CampaignSummaryViewModel))] [JsonSerializable(typeof(IndexViewModel))] @@ -38,6 +39,7 @@ public sealed class MetadataAndSerializationContextTests : RealWorldContextTests public override void EnsureFastPathGeneratedAsExpected() { Assert.NotNull(MetadataAndSerializationContext.Default.Location.Serialize); + Assert.NotNull(MetadataAndSerializationContext.Default.NumberTypes.Serialize); Assert.NotNull(MetadataAndSerializationContext.Default.RepeatedLocation.Serialize); Assert.NotNull(MetadataAndSerializationContext.Default.ActiveOrUpcomingEvent.Serialize); Assert.NotNull(MetadataAndSerializationContext.Default.CampaignSummaryViewModel.Serialize); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs index 101a53e02246a..e6d1fd754f10a 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs @@ -8,6 +8,7 @@ namespace System.Text.Json.SourceGeneration.Tests { [JsonSerializable(typeof(Location), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(RepeatedTypes.Location), TypeInfoPropertyName = "RepeatedLocation", GenerationMode = JsonSourceGenerationMode.Metadata)] + [JsonSerializable(typeof(NumberTypes), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(ActiveOrUpcomingEvent), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(CampaignSummaryViewModel), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(IndexViewModel), GenerationMode = JsonSourceGenerationMode.Metadata)] @@ -38,6 +39,7 @@ public override void EnsureFastPathGeneratedAsExpected() { Assert.Null(MetadataWithPerTypeAttributeContext.Default.Location.Serialize); Assert.Null(MetadataWithPerTypeAttributeContext.Default.RepeatedLocation.Serialize); + Assert.Null(MetadataWithPerTypeAttributeContext.Default.NumberTypes.Serialize); Assert.Null(MetadataWithPerTypeAttributeContext.Default.ActiveOrUpcomingEvent.Serialize); Assert.Null(MetadataWithPerTypeAttributeContext.Default.CampaignSummaryViewModel.Serialize); Assert.Null(MetadataWithPerTypeAttributeContext.Default.IndexViewModel.Serialize); @@ -59,6 +61,7 @@ public override void EnsureFastPathGeneratedAsExpected() [JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(Location))] [JsonSerializable(typeof(RepeatedTypes.Location), TypeInfoPropertyName = "RepeatedLocation")] + [JsonSerializable(typeof(NumberTypes))] [JsonSerializable(typeof(ActiveOrUpcomingEvent))] [JsonSerializable(typeof(CampaignSummaryViewModel))] [JsonSerializable(typeof(IndexViewModel))] @@ -89,6 +92,7 @@ public override void EnsureFastPathGeneratedAsExpected() { Assert.Null(MetadataContext.Default.Location.Serialize); Assert.Null(MetadataContext.Default.RepeatedLocation.Serialize); + Assert.Null(MetadataContext.Default.NumberTypes.Serialize); Assert.Null(MetadataContext.Default.ActiveOrUpcomingEvent.Serialize); Assert.Null(MetadataContext.Default.CampaignSummaryViewModel.Serialize); Assert.Null(MetadataContext.Default.IndexViewModel.Serialize); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs index aaf1f17fc2224..64371e837de2a 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs @@ -8,6 +8,7 @@ namespace System.Text.Json.SourceGeneration.Tests { [JsonSerializable(typeof(Location), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(RepeatedTypes.Location), TypeInfoPropertyName = "RepeatedLocation", GenerationMode = JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(NumberTypes), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(ActiveOrUpcomingEvent), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(CampaignSummaryViewModel), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(IndexViewModel), GenerationMode = JsonSourceGenerationMode.Metadata)] @@ -38,6 +39,7 @@ public override void EnsureFastPathGeneratedAsExpected() { Assert.Null(MixedModeContext.Default.Location.Serialize); Assert.NotNull(MixedModeContext.Default.RepeatedLocation.Serialize); + Assert.Null(MixedModeContext.Default.NumberTypes.Serialize); Assert.NotNull(MixedModeContext.Default.CampaignSummaryViewModel.Serialize); Assert.Null(MixedModeContext.Default.IndexViewModel.Serialize); Assert.Null(MixedModeContext.Default.WeatherForecastWithPOCOs.Serialize); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs index db55741cdca51..8831e42a66f87 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs @@ -33,6 +33,17 @@ public virtual void RoundTripLocation() VerifyLocation(expected, obj); } + [Fact] + public virtual void RoundTripNumberTypes() + { + NumberTypes expected = CreateNumberTypes(); + + string json = JsonSerializer.Serialize(expected, DefaultContext.NumberTypes); + NumberTypes obj = JsonSerializer.Deserialize(json, DefaultContext.NumberTypes); + VerifyNumberTypes(expected, obj); + } + + [Fact] public virtual void RoundTripIndexViewModel() { @@ -127,6 +138,39 @@ protected static void VerifyLocation(Location expected, Location obj) Assert.Equal(expected.Country, obj.Country); } + protected static NumberTypes CreateNumberTypes() + { + return new NumberTypes + { + Single = 1.1f, + Double = 2.2d, + Decimal = 3.3m, + SByte = -1, + Byte = 1, + UShort = 2, + Short = -2, + UInt = 3, + Int = -3, + ULong = 4, + Long = -4, + }; + } + + protected static void VerifyNumberTypes(NumberTypes expected, NumberTypes obj) + { + Assert.Equal(expected.Single, obj.Single); + Assert.Equal(expected.Double, obj.Double); + Assert.Equal(expected.Decimal, obj.Decimal); + Assert.Equal(expected.SByte, obj.SByte); + Assert.Equal(expected.Byte, obj.Byte); + Assert.Equal(expected.UShort, obj.UShort); + Assert.Equal(expected.Short, obj.Short); + Assert.Equal(expected.UInt, obj.UInt); + Assert.Equal(expected.Int, obj.Int); + Assert.Equal(expected.ULong, obj.ULong); + Assert.Equal(expected.Long, obj.Long); + } + protected static ActiveOrUpcomingEvent CreateActiveOrUpcomingEvent() { return new ActiveOrUpcomingEvent diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs index 0fb3c4e9ddef8..799de2b103210 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs @@ -9,6 +9,7 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(Location))] [JsonSerializable(typeof(RepeatedTypes.Location), TypeInfoPropertyName = "RepeatedLocation")] + [JsonSerializable(typeof(NumberTypes))] [JsonSerializable(typeof(ActiveOrUpcomingEvent))] [JsonSerializable(typeof(CampaignSummaryViewModel))] [JsonSerializable(typeof(IndexViewModel))] @@ -32,6 +33,7 @@ internal partial class SerializationContext : JsonSerializerContext, ITestContex [JsonSerializable(typeof(Location), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RepeatedTypes.Location), GenerationMode = JsonSourceGenerationMode.Serialization, TypeInfoPropertyName = "RepeatedLocation")] + [JsonSerializable(typeof(NumberTypes), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(ActiveOrUpcomingEvent), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(CampaignSummaryViewModel), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(IndexViewModel), GenerationMode = JsonSourceGenerationMode.Serialization)] @@ -56,6 +58,7 @@ internal partial class SerializationWithPerTypeAttributeContext : JsonSerializer [JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)] [JsonSerializable(typeof(Location), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RepeatedTypes.Location), GenerationMode = JsonSourceGenerationMode.Serialization, TypeInfoPropertyName = "RepeatedLocation")] + [JsonSerializable(typeof(NumberTypes), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(ActiveOrUpcomingEvent), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(CampaignSummaryViewModel), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(IndexViewModel), GenerationMode = JsonSourceGenerationMode.Serialization)] @@ -91,6 +94,7 @@ public override void EnsureFastPathGeneratedAsExpected() { Assert.NotNull(SerializationContext.Default.Location.Serialize); Assert.NotNull(SerializationContext.Default.RepeatedLocation.Serialize); + Assert.NotNull(SerializationContext.Default.NumberTypes.Serialize); Assert.NotNull(SerializationContext.Default.ActiveOrUpcomingEvent.Serialize); Assert.NotNull(SerializationContext.Default.CampaignSummaryViewModel.Serialize); Assert.NotNull(SerializationContext.Default.IndexViewModel.Serialize); @@ -124,6 +128,20 @@ public override void RoundTripLocation() AssertFastPathLogicCorrect(json, obj, DefaultContext.Location); } + [Fact] + public override void RoundTripNumberTypes() + { + NumberTypes expected = CreateNumberTypes(); + + string json = JsonSerializer.Serialize(expected, DefaultContext.NumberTypes); + JsonTestHelper.AssertThrows_PropMetadataInit(() => JsonSerializer.Deserialize(json, DefaultContext.NumberTypes), typeof(NumberTypes)); + + NumberTypes obj = JsonSerializer.Deserialize(json, ((ITestContext)MetadataWithPerTypeAttributeContext.Default).NumberTypes); + VerifyNumberTypes(expected, obj); + + AssertFastPathLogicCorrect(json, obj, DefaultContext.NumberTypes); + } + [Fact] public override void RoundTripIndexViewModel() { diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs index 50be97c82afc3..887f65b80da83 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs @@ -35,6 +35,21 @@ public class Location public string Country { get; set; } } + public class NumberTypes + { + public float Single { get; set; } + public double Double { get; set; } + public decimal Decimal { get; set; } + public sbyte SByte { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public short Short { get; set; } + public uint UInt { get; set; } + public int Int { get; set; } + public ulong ULong { get; set; } + public long Long { get; set; } + } + public class ActiveOrUpcomingEvent { public int Id { get; set; } From a35aff789d148cd7549cad9040026d05e160021d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 3 Aug 2021 15:31:28 -0700 Subject: [PATCH 2/9] [main] Update dependencies from mono/linker (#56593) * Update linker warning suppressions https://github.com/mono/linker/pull/2145 warns when accessing members annotated with DynamicallyAccessedMembers using reflection, and https://github.com/mono/linker/pull/2162 updates the warning origin of warnings for DynamicallyAccessedMembers on types. This adds suppressions for the new warnings. * Add windows-specific suppressions * Update dependencies from https://github.com/mono/linker build 20210729.2 Microsoft.NET.ILLink.Tasks From Version 6.0.100-preview.6.21378.1 -> To Version 6.0.100-preview.6.21379.2 * Fix failures and address feedback - Annotate mono's EnumBuilder and TypeBuilder - Add (non-unique) readable short names to the warning codes * Update dependencies from https://github.com/mono/linker build 20210730.2 Microsoft.NET.ILLink.Tasks From Version 6.0.100-preview.6.21378.1 -> To Version 6.0.100-preview.6.21380.2 * Suppress IL2111 * Update dependencies from https://github.com/mono/linker build 20210802.2 Microsoft.NET.ILLink.Tasks From Version 6.0.100-preview.6.21378.1 -> To Version 6.0.100-preview.6.21402.2 * Feedback - Suppress IL2111 in trimming tests - Remove unnecessary DynamicDependency - Fix indentation * Update readable warning names Co-authored-by: Sven Boemer Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 +- eng/Versions.props | 2 +- .../linker/SupportFiles/Directory.Build.props | 2 + eng/testing/tests.mobile.targets | 2 + .../Runtime/InteropServices/ComActivator.cs | 9 ++- .../VisualBasic/CompilerServices/IDOBinder.vb | 2 + .../Data/Common/DbConnectionStringBuilder.cs | 15 +++-- .../src/System/Data/DataSet.cs | 8 +-- .../src/System/Data/DataTable.cs | 6 +- .../src/System/Data/DataTableReader.cs | 9 ++- .../src/System/Data/TypedTableBase.cs | 6 +- .../src/ILLink/ILLink.Suppressions.xml | 7 ++- .../DiagnosticSourceEventSource.cs | 32 ++++++++-- .../TrimmingTests/EventSourceManifestTest.cs | 1 + .../Linq/Expressions/Compiler/AssemblyGen.cs | 3 + .../System/Diagnostics/Tracing/EventSource.cs | 61 +++++++++++++++++-- .../TraceLogging/TraceLoggingEventSource.cs | 12 ++++ .../Serialization/PrimitiveDataContract.cs | 7 ++- .../Reflection/Emit/EnumBuilder.Mono.cs | 4 ++ .../Reflection/Emit/TypeBuilder.Mono.cs | 4 ++ 20 files changed, 159 insertions(+), 37 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b1f8ce8b27f24..a0e2d9948f431 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -186,9 +186,9 @@ https://github.com/dotnet/runtime 95863758cd16c345d0b8fca067d5db5d6901e498 - + https://github.com/mono/linker - 0cb9250a903cfc90cbac602ed79c0cbc588d8d3f + ae18468b8712503aee67911228dd921601bd423a https://github.com/dotnet/xharness diff --git a/eng/Versions.props b/eng/Versions.props index 2a4f7a6a74987..40ac3dd8b148f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -166,7 +166,7 @@ 5.0.0-preview-20201009.2 - 6.0.100-preview.6.21378.1 + 6.0.100-preview.6.21402.2 $(MicrosoftNETILLinkTasksVersion) 6.0.0-rc.1.21369.1 diff --git a/eng/testing/linker/SupportFiles/Directory.Build.props b/eng/testing/linker/SupportFiles/Directory.Build.props index 760ff6d86e810..458994a1822eb 100644 --- a/eng/testing/linker/SupportFiles/Directory.Build.props +++ b/eng/testing/linker/SupportFiles/Directory.Build.props @@ -17,6 +17,8 @@ false true + + $(NoWarn);IL2111 diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 6c01e8c896742..3beee87d76049 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -17,6 +17,8 @@ true true + + $(NoWarn);IL2111 false diff --git a/src/coreclr/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs b/src/coreclr/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs index b8e21637d4851..6fdf4b2e5c311 100644 --- a/src/coreclr/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs +++ b/src/coreclr/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs @@ -523,10 +523,10 @@ private sealed class LicenseClassFactory : IClassFactory2 private readonly LicenseInteropProxy _licenseProxy = new LicenseInteropProxy(); private readonly Guid _classId; - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces | DynamicallyAccessedMemberTypes.PublicConstructors)] private readonly Type _classType; - public LicenseClassFactory(Guid clsid, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] Type classType) + public LicenseClassFactory(Guid clsid, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces | DynamicallyAccessedMemberTypes.PublicConstructors)] Type classType) { _classId = clsid; _classType = classType; @@ -627,6 +627,9 @@ internal sealed class LicenseInteropProxy private object? _licContext; private Type? _targetRcwType; + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2111:ReflectionToDynamicallyAccessedMembers", + Justification = "The type parameter to LicenseManager.CreateWithContext method has PublicConstructors annotation. We only invoke this method" + + "from AllocateAndValidateLicense which annotates the value passed in with the same annotation.")] public LicenseInteropProxy() { Type licManager = Type.GetType("System.ComponentModel.LicenseManager, System.ComponentModel.TypeConverter", throwOnError: true)!; @@ -742,7 +745,7 @@ public string RequestLicKey(Type type) // If we are being entered because of a call to ICF::CreateInstanceLic(), // "isDesignTime" will be "false" and "key" will point to a non-null // license key. - public object AllocateAndValidateLicense(Type type, string? key, bool isDesignTime) + public object AllocateAndValidateLicense([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type, string? key, bool isDesignTime) { object?[] parameters; object? licContext; diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/IDOBinder.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/IDOBinder.vb index 9644a77fd43df..cd20c96127205 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/IDOBinder.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/IDOBinder.vb @@ -824,6 +824,8 @@ Namespace Microsoft.VisualBasic.CompilerServices + Public Overrides Function FallbackConvert( ByVal target As DynamicMetaObject, ByVal errorSuggestion As DynamicMetaObject) As DynamicMetaObject diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs index 74feebf9a0493..13552bc01785e 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs @@ -12,10 +12,8 @@ namespace System.Data.Common { - // This coarse suppression silences all RequiresUnreferencedCode warnings in the class. - // https://github.com/mono/linker/issues/2136 tracks making it possible to add more granular suppressions at the member level, and with a different warning code. - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "The use of GetType preserves members with RequiresUnreferencedCode, but the GetType callsites either " + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2113:ReflectionToRequiresUnreferencedCode", + Justification = "The use of GetType preserves ICustomTypeDescriptor members with RequiresUnreferencedCode, but the GetType callsites either " + "occur in RequiresUnreferencedCode scopes, or have individually justified suppressions.")] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public class DbConnectionStringBuilder : IDictionary, ICustomTypeDescriptor @@ -393,6 +391,9 @@ internal Attribute[] GetAttributesFromCollection(AttributeCollection collection) return attributes; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "The use of GetType preserves this member with RequiresUnreferencedCode, but the GetType callsites either " + + "occur in RequiresUnreferencedCode scopes, or have individually justified suppressions.")] [RequiresUnreferencedCode("PropertyDescriptor's PropertyType cannot be statically discovered.")] private PropertyDescriptorCollection GetProperties() { @@ -419,6 +420,9 @@ private PropertyDescriptorCollection GetProperties() return propertyDescriptors; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "The use of GetType preserves this member with RequiresUnreferencedCode, but the GetType callsites either " + + "occur in RequiresUnreferencedCode scopes, or have individually justified suppressions.")] [RequiresUnreferencedCode("PropertyDescriptor's PropertyType cannot be statically discovered.")] protected virtual void GetProperties(Hashtable propertyDescriptors) { @@ -526,6 +530,9 @@ protected virtual void GetProperties(Hashtable propertyDescriptors) } } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "The use of GetType preserves this member with RequiresUnreferencedCode, but the GetType callsites either " + + "occur in RequiresUnreferencedCode scopes, or have individually justified suppressions.")] [RequiresUnreferencedCode("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] private PropertyDescriptorCollection GetProperties(Attribute[]? attributes) { diff --git a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs index 962ba8131b853..b2a85e44b382e 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs @@ -30,10 +30,6 @@ namespace System.Data [XmlSchemaProvider(nameof(GetDataSetSchema))] [XmlRoot(nameof(DataSet))] [System.Runtime.CompilerServices.TypeForwardedFrom("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - // This coarse suppression silences all RequiresUnreferencedCode warnings in the class. - // https://github.com/mono/linker/issues/2136 tracks making it possible to add more granular suppressions at the member level, and with a different warning code. - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "CreateInstanceOfThisType's use of GetType uses only the parameterless constructor, but the annotations preserve all non-public constructors causing a warning for the serialization constructors. Those constructors won't be used here.")] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.NonPublicConstructors)] // needed by Clone() to preserve derived ctors public class DataSet : MarshalByValueComponent, IListSource, IXmlSerializable, ISupportInitializeNotification, ISerializable { @@ -231,11 +227,15 @@ protected void GetSerializationData(SerializationInfo info, StreamingContext con // Deserialize all the tables schema and data of the dataset from binary/xml stream. [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "CreateInstanceOfThisType's use of GetType uses only the parameterless constructor, but the annotations preserve all non-public constructors causing a warning for the serialization constructors. Those constructors won't be used here.")] protected DataSet(SerializationInfo info, StreamingContext context) : this(info, context, true) { } [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "CreateInstanceOfThisType's use of GetType uses only the parameterless constructor, but the annotations preserve all non-public constructors causing a warning for the serialization constructors. Those constructors won't be used here.")] protected DataSet(SerializationInfo info, StreamingContext context, bool ConstructSchema) : this() { SerializationFormat remotingFormat = SerializationFormat.Xml; diff --git a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs index ad9044bd4a907..08648e6d29c26 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs @@ -31,10 +31,6 @@ namespace System.Data [XmlSchemaProvider(nameof(GetDataTableSchema))] [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - // This coarse suppression silences all RequiresUnreferencedCode warnings in the class. - // https://github.com/mono/linker/issues/2136 tracks making it possible to add more granular suppressions at the member level, and with a different warning code. - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "CreateInstance's use of GetType uses only the parameterless constructor. Warnings are about serialization related constructors.")] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public class DataTable : MarshalByValueComponent, IListSource, ISupportInitializeNotification, ISerializable, IXmlSerializable { @@ -196,6 +192,8 @@ public DataTable(string? tableName, string? tableNamespace) : this(tableName) } // Deserialize the table from binary/xml stream. + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "CreateInstance's use of GetType uses only the parameterless constructor. Warnings are about serialization related constructors.")] [RequiresUnreferencedCode(DataSet.RequiresUnreferencedCodeMessage)] protected DataTable(SerializationInfo info, StreamingContext context) : this() { diff --git a/src/libraries/System.Data.Common/src/System/Data/DataTableReader.cs b/src/libraries/System.Data.Common/src/System/Data/DataTableReader.cs index 2a14fa8f44476..58d56a332c63a 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataTableReader.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataTableReader.cs @@ -737,7 +737,14 @@ internal static DataTable GetSchemaTableFromDataTable(DataTable table) DataColumn ColumnSize = new DataColumn(SchemaTableColumn.ColumnSize, typeof(int)); DataColumn NumericPrecision = new DataColumn(SchemaTableColumn.NumericPrecision, typeof(short)); DataColumn NumericScale = new DataColumn(SchemaTableColumn.NumericScale, typeof(short)); - DataColumn DataType = new DataColumn(SchemaTableColumn.DataType, typeof(Type)); + DataColumn DataType = GetSystemTypeDataColumn(); + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2111:ReflectionToDynamicallyAccessedMembers", + Justification = "The problem is Type.TypeInitializer which requires constructors on the Type instance." + + "In this case the TypeInitializer property is not accessed dynamically.")] + static DataColumn GetSystemTypeDataColumn() => + new DataColumn(SchemaTableColumn.DataType, typeof(Type)); + DataColumn ProviderType = new DataColumn(SchemaTableColumn.ProviderType, typeof(int)); DataColumn IsLong = new DataColumn(SchemaTableColumn.IsLong, typeof(bool)); DataColumn AllowDBNull = new DataColumn(SchemaTableColumn.AllowDBNull, typeof(bool)); diff --git a/src/libraries/System.Data.Common/src/System/Data/TypedTableBase.cs b/src/libraries/System.Data.Common/src/System/Data/TypedTableBase.cs index 64fdf03878571..de17c7d2d82e4 100644 --- a/src/libraries/System.Data.Common/src/System/Data/TypedTableBase.cs +++ b/src/libraries/System.Data.Common/src/System/Data/TypedTableBase.cs @@ -12,10 +12,6 @@ namespace System.Data /// This is the generic base class for TypedDataSet /// [Serializable] - // This coarse suppression silences all RequiresUnreferencedCode warnings in the class. - // https://github.com/mono/linker/issues/2136 tracks making it possible to add more granular suppressions at the member level, and with a different warning code. - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "DataTable.CreateInstance's use of GetType uses only the parameterless constructor. Warnings are about serialization related constructors.")] public abstract class TypedTableBase : DataTable, IEnumerable where T : DataRow { @@ -32,6 +28,8 @@ protected TypedTableBase() : base() { } /// /// SerializationInfo containing data to construct the object. /// The streaming context for the object being deserialized. + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "DataTable.CreateInstance's use of GetType uses only the parameterless constructor, not this serialization related constructor.")] [RequiresUnreferencedCode(DataSet.RequiresUnreferencedCodeMessage)] protected TypedTableBase(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } diff --git a/src/libraries/System.Data.OleDb/src/ILLink/ILLink.Suppressions.xml b/src/libraries/System.Data.OleDb/src/ILLink/ILLink.Suppressions.xml index 63d7bd6ef89fd..d54caa4452859 100644 --- a/src/libraries/System.Data.OleDb/src/ILLink/ILLink.Suppressions.xml +++ b/src/libraries/System.Data.OleDb/src/ILLink/ILLink.Suppressions.xml @@ -97,5 +97,10 @@ member M:System.Data.OleDb.OleDbDataReader.GetFieldType(System.Int32) - + + ILLink + IL2111 + member + M:System.Data.OleDb.OleDbDataReader.BuildSchemaTable(MetaData[]) + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs index 31daa2a57eb5f..c7b92ad12ff2d 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs @@ -160,12 +160,17 @@ namespace System.Diagnostics /// See the DiagnosticSourceEventSourceBridgeTest.cs for more explicit examples of using this bridge. /// [EventSource(Name = "Microsoft-Diagnostics-DiagnosticSource")] - // This coarse suppression silences all RequiresUnreferencedCode warnings in the class. - // https://github.com/mono/linker/issues/2136 tracks making it possible to add more granular suppressions at the member level, and with a different warning code. - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves all members, so " + - "those that are marked with RequiresUnreferencedCode will warn. " + - "This method will not access any of these members and is safe to call.")] + // These suppressions can go away with https://github.com/mono/linker/issues/2175 + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2113:ReflectionToRequiresUnreferencedCode", + Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves methods on Delegate and MulticastDelegate " + + "because the nested type OverrideEventProvider's base type EventProvider defines a delegate. " + + "This includes Delegate and MulticastDelegate methods which require unreferenced code, but " + + "EnsureDescriptorsInitialized does not access these members and is safe to call.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2115:ReflectionToDynamicallyAccessedMembers", + Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves methods on Delegate and MulticastDelegate " + + "because the nested type OverrideEventProvider's base type EventProvider defines a delegate. " + + "This includes Delegate and MulticastDelegate methods which have dynamically accessed members requirements, but " + + "EnsureDescriptorsInitialized does not access these members and is safe to call.")] internal sealed class DiagnosticSourceEventSource : EventSource { public static DiagnosticSourceEventSource Log = new DiagnosticSourceEventSource(); @@ -1019,6 +1024,9 @@ private void Dispose() } } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(DiagnosticSource.WriteRequiresUnreferencedCode)] public List> Morph(object? args) { @@ -1100,6 +1108,9 @@ private void Dispose() // Given a type generate all the implicit transforms for type (that is for every field // generate the spec that fetches it). + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(DiagnosticSource.WriteRequiresUnreferencedCode)] private static TransformSpec? MakeImplicitTransforms(Type type) { @@ -1195,6 +1206,9 @@ public TransformSpec(string transformSpec, int startIdx, int endIdx, TransformSp /// if the spec is OUTSTR=EVENT_VALUE.PROP1.PROP2.PROP3 and the ultimate value of PROP3 is /// 10 then the return key value pair is KeyValuePair("OUTSTR","10") /// + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(DiagnosticSource.WriteRequiresUnreferencedCode)] public KeyValuePair Morph(object? obj) { @@ -1246,6 +1260,9 @@ public PropertySpec(string propertyName, PropertySpec? next) /// Given an object fetch the property that this PropertySpec represents. /// obj may be null when IsStatic is true, otherwise it must be non-null. /// + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(DiagnosticSource.WriteRequiresUnreferencedCode)] public object? Fetch(object? obj) { @@ -1289,6 +1306,9 @@ public PropertyFetch(Type? type) /// /// Create a property fetcher for a propertyName /// + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(DiagnosticSource.WriteRequiresUnreferencedCode)] public static PropertyFetch FetcherForProperty(Type? type, string propertyName) { diff --git a/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourceManifestTest.cs b/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourceManifestTest.cs index 91929da00c046..92dfa41915d14 100644 --- a/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourceManifestTest.cs +++ b/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourceManifestTest.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Tracing; using System.Linq; using System; diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/AssemblyGen.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/AssemblyGen.cs index bd6cfe7144b59..4f0ed87b7132b 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/AssemblyGen.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/AssemblyGen.cs @@ -60,6 +60,9 @@ private TypeBuilder DefineType(string name, [DynamicallyAccessedMembers(Dynamica [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "MulticastDelegate has a ctor with RequiresUnreferencedCode, but the generated derived type doesn't reference this ctor, so this is trim compatible.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2111:ReflectionToDynamicallyAccessedMembers", + Justification = "MulticastDelegate and Delegate have multiple methods with DynamicallyAccessedMembers annotations. But the generated code" + + "in this case will not call any of them (it only defines a .ctor and Invoke method both of which are runtime implemented.")] internal static TypeBuilder DefineDelegateType(string name) { return Assembly.DefineType( diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index e47a6127022cf..789a510bece12 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -233,12 +233,16 @@ internal sealed class EventSourceAutoGenerateAttribute : Attribute // The EnsureDescriptorsInitialized() method might need to access EventSource and its derived type // members and the trimmer ensures that these members are preserved. [DynamicallyAccessedMembers(ManifestMemberTypes)] - // This coarse suppression silences all RequiresUnreferencedCode warnings in the class. - // https://github.com/mono/linker/issues/2136 tracks making it possible to add more granular suppressions at the member level, and with a different warning code. - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "EnsureDescriptorsInitialized's use of GetType preserves all members, so " + - "those that are marked with RequiresUnreferencedCode will warn. " + - "This method will not access any of these members and is safe to call.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2113:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves methods on Delegate and MulticastDelegate " + + "because the nested type OverrideEventProvider's base type EventProvider defines a delegate. " + + "This includes Delegate and MulticastDelegate methods which require unreferenced code, but " + + "EnsureDescriptorsInitialized does not access these members and is safe to call.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2115:ReflectionToDynamicallyAccessedMembers", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves methods on Delegate and MulticastDelegate " + + "because the nested type OverrideEventProvider's base type EventProvider defines a delegate. " + + "This includes Delegate and MulticastDelegate methods which have dynamically accessed members requirements, but " + + "EnsureDescriptorsInitialized does not access these members and is safe to call.")] #endif public partial class EventSource : IDisposable { @@ -367,6 +371,12 @@ public static string GetName(Type eventSourceType) /// The manifest XML fragment contains the string name of the DLL name in /// which it is embedded. This parameter specifies what name will be used /// The XML data string +#if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2114:ReflectionToDynamicallyAccessedMembers", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "has dynamically accessed members requirements, but EnsureDescriptorsInitialized does not "+ + "access this member and is safe to call.")] +#endif public static string? GenerateManifest( #if !ES_BUILD_STANDALONE [DynamicallyAccessedMembers(ManifestMemberTypes)] @@ -388,6 +398,12 @@ public static string GetName(Type eventSourceType) /// The flags to customize manifest generation. If flags has bit OnlyIfNeededForRegistration specified /// this returns null when the eventSourceType does not require explicit registration /// The XML data string or null +#if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2114:ReflectionToDynamicallyAccessedMembers", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "has dynamically accessed members requirements, but EnsureDescriptorsInitialized does not "+ + "access this member and is safe to call.")] +#endif public static string? GenerateManifest( #if !ES_BUILD_STANDALONE [DynamicallyAccessedMembers(ManifestMemberTypes)] @@ -1269,6 +1285,9 @@ internal unsafe void SetMetadata(byte* pointer, int size, int reserved) /// /// #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] #endif [CLSCompliant(false)] @@ -1303,6 +1322,9 @@ protected unsafe void WriteEventCore(int eventId, int eventDataCount, EventSourc /// /// #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] #endif [CLSCompliant(false)] @@ -1398,6 +1420,9 @@ protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* rel /// check so that the varargs call is not made when the EventSource is not active. /// #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] #endif protected unsafe void WriteEvent(int eventId, params object?[] args) @@ -1414,6 +1439,9 @@ protected unsafe void WriteEvent(int eventId, params object?[] args) /// check so that the varargs call is not made when the EventSource is not active. /// #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] #endif protected unsafe void WriteEventWithRelatedActivityId(int eventId, Guid relatedActivityId, params object?[] args) @@ -1898,6 +1926,9 @@ private static unsafe void AssertValidString(EventData* data) } #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] #endif private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object?[] args) @@ -2010,6 +2041,9 @@ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object } #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] #endif private unsafe object?[] SerializeEventArgs(int eventId, object?[] args) @@ -2469,6 +2503,9 @@ internal partial struct EventMetadata public TraceLoggingEventTypes TraceLoggingEventTypes { #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] #endif get @@ -2956,6 +2993,12 @@ internal static bool IsCustomAttributeDefinedHelper( // Helper to deal with the fact that the type we are reflecting over might be loaded in the ReflectionOnly context. // When that is the case, we have the build the custom assemblies on a member by hand. +#if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2114:ReflectionToDynamicallyAccessedMembers", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "has dynamically accessed members requirements, but EnsureDescriptorsInitialized does not "+ + "access this member and is safe to call.")] +#endif internal static Attribute? GetCustomAttributeHelper( MemberInfo member, #if !ES_BUILD_STANDALONE @@ -3077,6 +3120,12 @@ private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAt // return the UTF8 bytes. It also sets up the code:EventData structures needed to dispatch events // at run time. 'source' is the event source to place the descriptors. If it is null, // then the descriptors are not created, and just the manifest is generated. +#if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2114:ReflectionToDynamicallyAccessedMembers", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "has dynamically accessed members requirements, but its use of this method satisfies " + + "these requirements because it passes in the result of GetType with the same annotations.")] +#endif private static byte[]? CreateManifestAndDescriptors( #if !ES_BUILD_STANDALONE [DynamicallyAccessedMembers(ManifestMemberTypes)] diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs index c51d731e0c61e..b6b739f3eeeb5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs @@ -163,6 +163,9 @@ public unsafe void Write(string? eventName, EventSourceOptions options) /// create the fields of the event. /// #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] public unsafe void Write<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>( #else @@ -204,6 +207,9 @@ public unsafe void Write( /// create the fields of the event. /// #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] public unsafe void Write<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>( #else @@ -247,6 +253,9 @@ public unsafe void Write( /// create the fields of the event. /// #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] public unsafe void Write<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>( #else @@ -297,6 +306,9 @@ public unsafe void Write( /// create the fields of the event. /// #if !ES_BUILD_STANDALONE + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2112:ReflectionToRequiresUnreferencedCode", + Justification = "EnsureDescriptorsInitialized's use of GetType preserves this method which " + + "requires unreferenced code, but EnsureDescriptorsInitialized does not access this member and is safe to call.")] [RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)] public unsafe void Write<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>( #else diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/PrimitiveDataContract.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/PrimitiveDataContract.cs index 8793954253a00..f7513edfd6720 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/PrimitiveDataContract.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/PrimitiveDataContract.cs @@ -345,7 +345,12 @@ internal sealed class NullPrimitiveDataContract : PrimitiveDataContract { [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This warns because the call to Base has the type annotated with DynamicallyAccessedMembers so it warns" + - "when looking into the methods of NullPrimitiveDataContract. Because this just represents null, we suppress.")] + "when looking into the methods of NullPrimitiveDataContract which are annotated with RequiresUnreferencedCodeAttribute. " + + "Because this just represents null, we suppress.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2111:ReflectionToDynamicallyAccessedMembers", + Justification = "This warns because the call to Base has the type annotated with DynamicallyAccessedMembers so it warns" + + "when looking into the methods of NullPrimitiveDataContract which are annotated with DynamicallyAccessedMembersAttribute. " + + "Because this just represents null, we suppress.")] public NullPrimitiveDataContract() : base(typeof(NullPrimitiveDataContract), DictionaryGlobals.EmptyString, DictionaryGlobals.EmptyString) { diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.Mono.cs index 39acd0deb5a9f..91dff62fa1fbc 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.Mono.cs @@ -209,6 +209,10 @@ public override Type GetEnumUnderlyingType() return _underlyingType; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2110:ReflectionToDynamicallyAccessedMembers", + Justification = "For instance members with MethodImplOptions.InternalCall, the linker preserves all fields of the declaring type. " + + "The _tb field has DynamicallyAccessedMembersAttribute requirements, but the field access is safe because " + + "Reflection.Emit is not subject to trimming.")] [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void setup_enum_type(Type t); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs index 26bca9f69f234..f2b83fbc7684f 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs @@ -752,6 +752,10 @@ public ConstructorBuilder DefineTypeInitializer() null); } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2110:ReflectionToDynamicallyAccessedMembers", + Justification = "For instance member internal calls, the linker preserves all fields of the declaring type. " + + "The parent and created fields have DynamicallyAccessedMembersAttribute requirements, but creating the runtime class is safe " + + "because the annotations fully preserve the parent type, and the type created via Reflection.Emit is not subject to trimming.")] [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern TypeInfo create_runtime_class(); From da803ac809dcf03c689079b2f707f5a4e1e15653 Mon Sep 17 00:00:00 2001 From: imhameed Date: Tue, 3 Aug 2021 18:49:26 -0400 Subject: [PATCH 3/9] CoreCLR runtime tests + Mono on the x64 iOS simulator (#43954) This creates another `runtime-staging` lane, named "Build iOSSimulator x64 Release AllSubsets_Mono_RuntimeTests", that will eventually run the runtime test suite against Mono's non-LLVM JIT on the iOS simulator on amd64 hosts. Failing tests are added to the exclusion lists in issues.targets. The tests aren't set to run yet, because they currently take a very long time to execute. `AppleAppBuilder` no longer requires a `MainLibraryFileName`. If omitted, one must be supplied when the app bundle is launched via an environment variable named `MONO_APPLE_APP_ENTRY_POINT_LIB_NAME`. The generated apps also accept another environment variable named `MONO_APPLE_APP_ASSEMBLY_LOAD_PREFIX`, which is a hack used to allow assembly lookup to proceed in a nested app-relative subdirectory before falling back to the root of the app bundle. This is necessary because app bundles contain multiple individual test assemblies, and these assemblies sometimes have dependencies with names that collide with the dependencies of other test assemblies inside the bundle. --- .../coreclr/templates/helix-queues-setup.yml | 10 +- eng/pipelines/runtime-staging.yml | 42 +++++ src/tasks/AppleAppBuilder/AppleAppBuilder.cs | 13 +- src/tasks/AppleAppBuilder/Templates/runtime.m | 61 +++++-- src/tests/Common/CLRTest.Execute.Bash.targets | 92 +++++++--- .../Coreclr.TestWrapper/MobileAppHandler.cs | 11 +- src/tests/Common/helixpublishwitharcade.proj | 15 +- src/tests/Common/tests.targets | 10 +- src/tests/Directory.Build.targets | 2 +- src/tests/Interop/ICastable/Castable.csproj | 2 +- src/tests/build.sh | 11 +- src/tests/issues.targets | 160 ++++++++++++++++++ src/tests/run.proj | 106 ++++++++++++ 13 files changed, 471 insertions(+), 64 deletions(-) diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index e6a413266ae13..2b3a80ce94349 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -26,18 +26,22 @@ jobs: runtimeFlavorDisplayName: ${{ parameters.runtimeFlavorDisplayName }} helixQueues: + # iOS/tvOS simulator x64/x86 + - ${{ if in(parameters.platform, 'iOSSimulator_x64', 'tvOSSimulator_x64') }}: + - OSX.1015.Amd64.Open + # Android arm64 - ${{ if in(parameters.platform, 'Android_arm64') }}: - Windows.10.Amd64.Android.Open - + # Android x64 - ${{ if in(parameters.platform, 'Android_x64') }}: - Ubuntu.1804.Amd64.Android.Open - + # Browser wasm - ${{ if eq(parameters.platform, 'Browser_wasm') }}: - Ubuntu.1804.Amd64.Open - + # Linux arm - ${{ if eq(parameters.platform, 'Linux_arm') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index 27843c8959dd4..92e672c5b187c 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -259,6 +259,48 @@ jobs: creator: dotnet-bot testRunNamePrefixSuffix: Mono_$(_BuildConfig) +# +# Build the whole product using Mono and run runtime tests with the JIT. +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + buildConfig: Release + runtimeFlavor: mono + platforms: + - iOSSimulator_x64 + variables: + - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}: + - name: _HelixSource + value: pr/dotnet/runtime/$(Build.SourceBranch) + - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}: + - name: _HelixSource + value: ci/dotnet/runtime/$(Build.SourceBranch) + - name: timeoutPerTestInMinutes + value: 60 + - name: timeoutPerTestCollectionInMinutes + value: 180 + jobParameters: + testGroup: innerloop + nameSuffix: AllSubsets_Mono_RuntimeTests + buildArgs: -s mono+libs -c $(_BuildConfig) + timeoutInMinutes: 240 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true), + eq(variables['isFullMatrix'], true)) + # Test execution is temporarily disabled because test apps no longer launch + # and the test suite times out after two hours, even if xharness cannot + # successfully launch any tests. Re-enable once these issues have been fixed. + # + # extra steps, run tests + # extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml + # extraStepsParameters: + # creator: dotnet-bot + # testRunNamePrefixSuffix: Mono_$(_BuildConfig) + # # Build the whole product using Mono for Android and run runtime tests with Android devices # diff --git a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs index 6183fe0442f2a..9127192f9f6c4 100644 --- a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs +++ b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs @@ -50,9 +50,11 @@ public string TargetOS public string MonoRuntimeHeaders { get; set; } = ""!; /// - /// This library will be used as an entry-point (e.g. TestRunner.dll) + /// This library will be used as an entry point (e.g. TestRunner.dll). Can + /// be empty. If empty, the entry point of the app must be specified in an + /// environment variable named "MONO_APPLE_APP_ENTRY_POINT_LIB_NAME" when + /// running the resulting app. /// - [Required] public string MainLibraryFileName { get; set; } = ""!; /// @@ -155,9 +157,12 @@ public override bool Execute() { bool isDevice = (TargetOS == TargetNames.iOS || TargetOS == TargetNames.tvOS); - if (!File.Exists(Path.Combine(AppDir, MainLibraryFileName))) + if (!string.IsNullOrEmpty(MainLibraryFileName)) { - throw new ArgumentException($"MainLibraryFileName='{MainLibraryFileName}' was not found in AppDir='{AppDir}'"); + if (!File.Exists(Path.Combine(AppDir, MainLibraryFileName))) + { + throw new ArgumentException($"MainLibraryFileName='{MainLibraryFileName}' was not found in AppDir='{AppDir}'"); + } } if (ProjectName.Contains(' ')) diff --git a/src/tasks/AppleAppBuilder/Templates/runtime.m b/src/tasks/AppleAppBuilder/Templates/runtime.m index de9ca63b86838..3146f05b7f73c 100644 --- a/src/tasks/AppleAppBuilder/Templates/runtime.m +++ b/src/tasks/AppleAppBuilder/Templates/runtime.m @@ -86,13 +86,33 @@ munmap (handle, size); } -static MonoAssembly* +static const char *assembly_load_prefix = NULL; + +static MonoAssembly * +load_assembly_aux (const char *filename, const char *culture, const char *bundle) +{ + char path [1024]; + int res; + if (culture && strcmp (culture, "")) + res = snprintf (path, sizeof (path) - 1, "%s/%s/%s", bundle, culture, filename); + else + res = snprintf (path, sizeof (path) - 1, "%s/%s", bundle, filename); + assert (res > 0); + + struct stat buffer; + if (stat (path, &buffer) == 0) { + MonoAssembly *assembly = mono_assembly_open (path, NULL); + assert (assembly); + return assembly; + } + return NULL; +} + +static MonoAssembly * load_assembly (const char *name, const char *culture) { const char *bundle = get_bundle_path (); char filename [1024]; - char path [1024]; - int res; os_log_info (OS_LOG_DEFAULT, "assembly_preload_hook: %{public}s %{public}s %{public}s\n", name, culture, bundle); @@ -105,19 +125,14 @@ strlcat (filename, ".dll", sizeof (filename)); } - if (culture && strcmp (culture, "")) - res = snprintf (path, sizeof (path) - 1, "%s/%s/%s", bundle, culture, filename); - else - res = snprintf (path, sizeof (path) - 1, "%s/%s", bundle, filename); - assert (res > 0); - - struct stat buffer; - if (stat (path, &buffer) == 0) { - MonoAssembly *assembly = mono_assembly_open (path, NULL); - assert (assembly); - return assembly; + if (assembly_load_prefix [0] != '\0') { + char prefix_bundle [1024]; + int res = snprintf (prefix_bundle, sizeof (prefix_bundle) - 1, "%s/%s", bundle, assembly_load_prefix); + assert (res > 0); + MonoAssembly *ret = load_assembly_aux (filename, culture, prefix_bundle); + if (ret) return ret; } - return NULL; + return load_assembly_aux (filename, culture, bundle); } static MonoAssembly* @@ -260,7 +275,7 @@ // TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES const char *appctx_keys [] = { - "RUNTIME_IDENTIFIER", + "RUNTIME_IDENTIFIER", "APP_CONTEXT_BASE_DIRECTORY", #if !defined(INVARIANT_GLOBALIZATION) "ICU_DAT_FILE_PATH" @@ -291,6 +306,19 @@ free (file_path); } + const char* executable = "%EntryPointLibName%"; + if (executable [0] == '\0') { + executable = getenv ("MONO_APPLE_APP_ENTRY_POINT_LIB_NAME"); + } + if (executable == NULL) { + executable = ""; + } + + assembly_load_prefix = getenv ("MONO_APPLE_APP_ASSEMBLY_LOAD_PREFIX"); + if (assembly_load_prefix == NULL) { + assembly_load_prefix = ""; + } + monovm_initialize (sizeof (appctx_keys) / sizeof (appctx_keys [0]), appctx_keys, appctx_values); #if (FORCE_INTERPRETER && !FORCE_AOT) @@ -334,7 +362,6 @@ MONO_EXIT_GC_UNSAFE; #endif - const char* executable = "%EntryPointLibName%"; MonoAssembly *assembly = load_assembly (executable, NULL); assert (assembly); os_log_info (OS_LOG_DEFAULT, "Executable: %{public}s", executable); diff --git a/src/tests/Common/CLRTest.Execute.Bash.targets b/src/tests/Common/CLRTest.Execute.Bash.targets index 7031b45d72e95..ee375b8069417 100644 --- a/src/tests/Common/CLRTest.Execute.Bash.targets +++ b/src/tests/Common/CLRTest.Execute.Bash.targets @@ -11,7 +11,7 @@ This file contains the logic for providing Execution Script generation. WARNING: When setting properties based on their current state (for example: - - + @@ -124,11 +124,11 @@ fi if [ -z ${CLRTestExpectedExitCode+x} ]%3B then export CLRTestExpectedExitCode=$(CLRTestExitCode)%3B fi echo BEGIN EXECUTION]]> - + - + - + @@ -188,29 +188,29 @@ ReflectionRoots= shopt -s nullglob -if [ ! -z "$DoLink" ]; +if [ ! -z "$DoLink" ]; then - if [ ! -x "$ILLINK" ]; + if [ ! -x "$ILLINK" ]; then echo "Illink executable [$ILLINK] Invalid" exit 1 fi - + # Clean up old Linked binaries, if any rm -rf $LinkBin - + # Remove Native images, since the goal is to run from Linked binaries rm -f *.ni.* # Use hints for reflection roots, if provided in $(ReflectionRootsXml) - if [ -f $(ReflectionRootsXml) ]; + if [ -f $(ReflectionRootsXml) ]; then ReflectionRoots="-x $(ReflectionRootsXml)" fi # Include all .exe files in this directory as entry points (some tests had multiple .exe file modules) - for bin in *.exe *.dll; - do + for bin in *.exe *.dll; + do Assemblies="$Assemblies -a ${bin%.*}" done @@ -224,14 +224,14 @@ then if [ $ERRORLEVEL -ne 0 ] then echo ILLINK FAILED $ERRORLEVEL - if [ -z "$KeepLinkedBinaries" ]; + if [ -z "$KeepLinkedBinaries" ]; then rm -rf $LinkBin fi exit 1 fi - - # Copy CORECLR native binaries to $LinkBin, + + # Copy CORECLR native binaries to $LinkBin, # so that we can run the test based on that directory cp $CORE_ROOT/*.so $LinkBin/ cp $CORE_ROOT/corerun $LinkBin/ @@ -252,9 +252,9 @@ fi # Clean up the LinkBin directories after test execution. # Otherwise, RunTests may run out of disk space. -if [ ! -z "$DoLink" ]; +if [ ! -z "$DoLink" ]; then - if [ -z "$KeepLinkedBinaries" ]; + if [ -z "$KeepLinkedBinaries" ]; then rm -rf $LinkBin fi @@ -364,7 +364,43 @@ fi $__Command $HARNESS_RUNNER android run --instrumentation="net.dot.MonoRunner" --package-name="net.dot.$__Category" --output-directory="$__OutputDir" --arg=entrypoint:libname=$(MsBuildProjectName).dll --expected-exit-code=100 -v CLRTestExitCode=$? -# Exist code of xharness is zero when tests finished successfully +# Exit code of xharness is zero when tests finished successfully +CLRTestExpectedExitCode=0 + ]]> + + + @@ -383,17 +419,17 @@ CLRTestExpectedExitCode=0 @(CLRTestBashEnvironmentVariable -> '%(Identity)', '%0a') - + - + <_RequiredProperties Include="_CLRTestRunFile"> $(_CLRTestRunFile) - + @@ -407,7 +443,7 @@ CLRTestExpectedExitCode=0 usage() { echo "Usage: $0 $(_CLRTestParamList)" - echo + echo echo "Arguments:" @(BashCLRTestExecutionScriptArgument -> ' echo "-%(Identity)=%(ParamName)" echo "%(Description)"', ' @@ -498,14 +534,14 @@ $(BashCLRTestExitCodeCheck) - + diff --git a/src/tests/Common/Coreclr.TestWrapper/MobileAppHandler.cs b/src/tests/Common/Coreclr.TestWrapper/MobileAppHandler.cs index f4d179ce4ce29..7a58262a95420 100644 --- a/src/tests/Common/Coreclr.TestWrapper/MobileAppHandler.cs +++ b/src/tests/Common/Coreclr.TestWrapper/MobileAppHandler.cs @@ -81,6 +81,11 @@ private static int HandleMobileApp(string action, string platform, string catego } } + if (platform != "android") + { + cmdStr += " --target ios-simulator-64"; + } + using (Process process = new Process()) { if (OperatingSystem.IsWindows()) @@ -97,6 +102,8 @@ private static int HandleMobileApp(string action, string platform, string catego process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; + outputWriter.WriteLine("XXXih: cmdStr = {0}", cmdStr); + errorWriter.WriteLine("XXXih: cmdStr = {0}", cmdStr); DateTime startTime = DateTime.Now; process.Start(); @@ -125,7 +132,7 @@ private static int HandleMobileApp(string action, string platform, string catego cmdStr, timeout, startTime.ToString(), endTime.ToString()); errorWriter.WriteLine("\ncmdLine:{0} Timed Out (timeout in milliseconds: {1}, start: {2}, end: {3})", cmdStr, timeout, startTime.ToString(), endTime.ToString()); - + process.Kill(entireProcessTree: true); } } @@ -152,7 +159,7 @@ private static string ConvertCmd2Arg(string cmd) { cmdPrefix = "-c"; } - + return $"{cmdPrefix} \"{cmd}\""; } } diff --git a/src/tests/Common/helixpublishwitharcade.proj b/src/tests/Common/helixpublishwitharcade.proj index b98bd8e8289b1..349530a5b2253 100644 --- a/src/tests/Common/helixpublishwitharcade.proj +++ b/src/tests/Common/helixpublishwitharcade.proj @@ -83,6 +83,7 @@ linux-musl-$(TargetArchitecture) browser-wasm android-$(TargetArchitecture) + iossimulator-$(TargetArchitecture) @@ -107,7 +108,15 @@ win-x64 - + + sdk + $([System.IO.File]::ReadAllText('$(RepoRoot)global.json')) + $([System.Text.RegularExpressions.Regex]::Match($(GlobalJsonContent), '(%3F<="dotnet": ").*(%3F=")')) + + osx-x64 + + + true @@ -156,6 +165,8 @@ <_PayloadFiles Include="@(_TestGroupingRelevant->WithMetadataValue('TestGroup','$(_PayloadGroup)')->DistinctWithCase())" Condition="'$(_TestGroupingExists)' == 'true'" /> <_PayloadFiles Include="$(_FileDirectory)*" Condition="'$(_TestGroupingExists)' == 'true'" /> + <_PayloadFiles Include="$(_FileDirectory)/*.app" Condition="'$(_TestGroupingExists)' == 'true'" /> + <_PayloadFiles Include="$(_FileDirectory)/*.app/**" Condition="'$(_TestGroupingExists)' == 'true'" /> <_PayloadFiles Update="@(_PayloadFiles)"> + Condition="'@(NativeProjectBinaries)' == '' And '$(TargetOS)' != 'Browser' And '$(TargetOS)' != 'Android' And '$(TargetOS)' != 'iOS' And '$(TargetOS)' != 'iOSSimulator'"/> Exe true - true + true diff --git a/src/tests/build.sh b/src/tests/build.sh index 7bd0ca06d85d6..ada962503ad62 100755 --- a/src/tests/build.sh +++ b/src/tests/build.sh @@ -51,6 +51,13 @@ build_mono_aot() build_MSBuild_projects "Tests_MonoAot" "$__RepoRootDir/src/tests/run.proj" "Mono AOT compile tests" "/t:MonoAotCompileTests" "/p:RuntimeFlavor=$__RuntimeFlavor" "/p:MonoBinDir=$__MonoBinDir" } +build_ios_apps() +{ + __RuntimeFlavor="mono" \ + __Exclude="$__RepoRootDir/src/tests/issues.targets" \ + build_MSBuild_projects "Create_iOS_App" "$__RepoRootDir/src/tests/run.proj" "Create iOS Apps" "/t:BuildAlliOSApp" +} + generate_layout() { echo "${__MsgPrefix}Creating test overlay..." @@ -256,7 +263,7 @@ build_Tests() fi fi - if [[ "$__SkipNative" != 1 && "$__TargetOS" != "Browser" && "$__TargetOS" != "Android" ]]; then + if [[ "$__SkipNative" != 1 && "$__TargetOS" != "Browser" && "$__TargetOS" != "Android" && "$__TargetOS" != "iOS" && "$__TargetOS" != "iOSSimulator" ]]; then build_native "$__TargetOS" "$__BuildArch" "$__TestDir" "$__NativeTestIntermediatesDir" "install" "CoreCLR test component" if [[ "$?" -ne 0 ]]; then @@ -624,6 +631,8 @@ echo "${__MsgPrefix}Test binaries are available at ${__TestBinDir}" if [ "$__TargetOS" == "Android" ]; then build_MSBuild_projects "Create_Android_App" "$__RepoRootDir/src/tests/run.proj" "Create Android Apps" "/t:BuildAllAndroidApp" "/p:RunWithAndroid=true" +elif [ "$__TargetOS" == "iOS" ] || [ "$__TargetOS" == "iOSSimulator" ]; then + build_ios_apps fi if [[ "$__RunTests" -ne 0 ]]; then diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 747903cb427ad..d121409c54bd3 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -2910,4 +2910,164 @@ https://github.com/dotnet/runtime/issues/52781 + + + + missing assembly + + + missing assembly + + + missing assembly + + + missing assembly + + + missing assembly + + + missing assembly + + + missing assembly + + + missing assembly + + + System.PlatformNotSupportedException: Operation is not supported on this platform + + + System.DllNotFoundException: DoesNotExist + + + System.DllNotFoundException: DoesNotExist + + + System.DllNotFoundException: UnmanagedCallersOnlyDll + + + System.DllNotFoundException: ObjectiveC + + + System.DllNotFoundException: SuppressGCTransitionNative + + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.assert, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c' or one of its dependencies. + + + System.DllNotFoundException: GCPollNative + + + + System.ArgumentNullException: Value cannot be null. (Parameter 'path1') + + + System.Exception: Values for 'retCode' are not equal! Left='1' Right='0' + + + + System.IO.FileNotFoundException: Could not load file or assembly '/.../Library/Developer/CoreSimulator/Devices/941235AB-7563-4D79-AC28-946B7AD2304A/data/Containers/Bundle/Application/40176A30-D8F5-4497-958A-6514E5C684FC/readytorun_multifolder.app/testdir-multifolder/../FolderA/FolderA/FolderA.dll' or one of its dependencies. + + + + Failed to catch an exception! System.DllNotFoundException: ForeignThreadExceptionsNative + + + + USAGE: MultipleWR.exe num objects [track] + + + USAGE: MultipleWR.exe num objects [track] + + + GC_API 0|1|2 + + + GC_API 0|1|2 + + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.runner.utility.netcoreapp10, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c' or one of its dependencies. + + + + Environment variable is not set: 'CORE_ROOT' + + + + USAGE: ThreadStartBool bool + + + USAGE: ThreadStartBool bool + + + + System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') + + + + System.DllNotFoundException: ThisCallNative + + + https://github.com/dotnet/runtime/issues/50440 + + + https://github.com/dotnet/runtime/issues/50440 + + + https://github.com/dotnet/runtime/issues/50440 + + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + This test requires CORE_ROOT to be set + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.assert, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + ((null) error) * Assertion at runtime/src/mono/mono/metadata/assembly.c:2049, condition `is_ok (error)' not met, function:mono_assembly_load_friends, Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + System.IO.FileNotFoundException: Could not load file or assembly 'xunit.performance.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=67066efe964d3b03' or one of its dependencies. + + + + CORE_ROOT must be set + + + + Could not load file or assembly 'System.Drawing.Common, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. + + diff --git a/src/tests/run.proj b/src/tests/run.proj index 4f17417636d84..f21a0bd128406 100644 --- a/src/tests/run.proj +++ b/src/tests/run.proj @@ -707,6 +707,112 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\",""). + + + + + + $([System.IO.Path]::GetDirectoryName($([System.IO.Path]::GetDirectoryName($(_CMDDIR))))) + $([System.String]::Copy('$(_CMDDIR)').Replace("$(CMDDIR_Grandparent)/","")) + $([System.String]::Copy('$(CategoryWithSlash)').Replace('/','_')) + $([System.String]::Copy('$(CategoryWithSlash)').Replace('/', '.')).XUnitWrapper.dll + $(CMDDIR_GrandParent)/$(CategoryWithSlash)/$(XUnitWrapperFileName) + $(IntermediateOutputPath)\iOSApps\$(Category) + $(XUnitTestBinBase)$(CategoryWithSlash)\$(Category).app + + + + $(Category) + $(ArtifactsBinDir)microsoft.netcore.app.runtime.iossimulator-$(TargetArchitecture)/$(Configuration)/runtimes/iossimulator-$(TargetArchitecture) + $(MicrosoftNetCoreAppRuntimePackDir)/native + + + + + + + + + + + + + + + @(TestDlls->'%(Filename)') + + + + $([MSBuild]::NormalizeDirectory('$(BuildDir)', 'AppBundle')) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _CMDDIR=%(TestDirectories.Identity) + + + + + From 890ea06859e3c9419fe39c90fde6f3a697f381c0 Mon Sep 17 00:00:00 2001 From: Nikola Milosavljevic Date: Tue, 3 Aug 2021 16:00:08 -0700 Subject: [PATCH 4/9] Enable SxS install of previews on Mac OS (#56797) --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a0e2d9948f431..50d864340935e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -50,9 +50,9 @@ https://github.com/dotnet/arcade c6a28c81f96d196338b3ea520bc1e6dc7c440ee2 - + https://github.com/dotnet/arcade - c6a28c81f96d196338b3ea520bc1e6dc7c440ee2 + 35a36a8ec705945b20275a7d63478affb396ff89 https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index 40ac3dd8b148f..bc6adff45db4d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,7 +60,7 @@ 6.0.0-beta.21373.11 2.5.1-beta.21373.11 6.0.0-beta.21373.11 - 6.0.0-beta.21373.11 + 6.0.0-beta.21403.2 6.0.0-beta.21373.11 6.0.0-beta.21373.11 6.0.0-beta.21373.11 From 4fa710e22f1035e597c00427ec86de772eb17666 Mon Sep 17 00:00:00 2001 From: Jeff Handley Date: Tue, 3 Aug 2021 19:28:42 -0400 Subject: [PATCH 5/9] Mark HandleProcessCorruptedStateExceptionsAttribute as obsolete (#56664) --- docs/project/list-of-diagnostics.md | 1 + src/libraries/Common/src/System/Obsoletions.cs | 3 +++ src/libraries/Directory.Build.targets | 3 ++- .../HandleProcessCorruptedStateExceptionsAttribute.cs | 1 + src/libraries/System.Runtime/ref/System.Runtime.cs | 1 + .../ExceptionServices/HandleProcessCorruptedStateExceptions.cs | 2 ++ src/tests/JIT/RyuJIT/DoWhileBndChk.cs | 2 ++ 7 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/project/list-of-diagnostics.md b/docs/project/list-of-diagnostics.md index cfb593d70b54d..5387dd5a0d748 100644 --- a/docs/project/list-of-diagnostics.md +++ b/docs/project/list-of-diagnostics.md @@ -86,6 +86,7 @@ The PR that reveals the implementation of the ` - $(NoWarn);SYSLIB0003;SYSLIB0004;SYSLIB0015;SYSLIB0017;SYSLIB0021;SYSLIB0022;SYSLIB0023;SYSLIB0025 + $(NoWarn);SYSLIB0003;SYSLIB0004;SYSLIB0015;SYSLIB0017;SYSLIB0021;SYSLIB0022;SYSLIB0023;SYSLIB0025;SYSLIB0032 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/ExceptionServices/HandleProcessCorruptedStateExceptionsAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/ExceptionServices/HandleProcessCorruptedStateExceptionsAttribute.cs index d77d20e85c0ef..0fc65d64151a9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/ExceptionServices/HandleProcessCorruptedStateExceptionsAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/ExceptionServices/HandleProcessCorruptedStateExceptionsAttribute.cs @@ -6,6 +6,7 @@ namespace System.Runtime.ExceptionServices // This attribute can be applied to methods to indicate that ProcessCorruptedState // Exceptions should be delivered to them. [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] + [Obsolete(Obsoletions.CorruptedStateRecoveryMessage, DiagnosticId = Obsoletions.CorruptedStateRecoveryDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public sealed class HandleProcessCorruptedStateExceptionsAttribute : Attribute { public HandleProcessCorruptedStateExceptionsAttribute() diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 380e0a2e7f100..93f41f4c996dc 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -13234,6 +13234,7 @@ public FirstChanceExceptionEventArgs(System.Exception exception) { } public System.Exception Exception { get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)] + [System.ObsoleteAttribute("Recovery from corrupted process state exceptions is not supported; HandleProcessCorruptedStateExceptionsAttribute is ignored.", DiagnosticId = "SYSLIB0032", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public sealed partial class HandleProcessCorruptedStateExceptionsAttribute : System.Attribute { public HandleProcessCorruptedStateExceptionsAttribute() { } diff --git a/src/libraries/System.Runtime/tests/System/Runtime/ExceptionServices/HandleProcessCorruptedStateExceptions.cs b/src/libraries/System.Runtime/tests/System/Runtime/ExceptionServices/HandleProcessCorruptedStateExceptions.cs index d594b07041912..99fee3dbf5b14 100644 --- a/src/libraries/System.Runtime/tests/System/Runtime/ExceptionServices/HandleProcessCorruptedStateExceptions.cs +++ b/src/libraries/System.Runtime/tests/System/Runtime/ExceptionServices/HandleProcessCorruptedStateExceptions.cs @@ -10,6 +10,8 @@ using Microsoft.DotNet.RemoteExecutor; using Xunit; +#pragma warning disable SYSLIB0032 // HandleProcessCorruptedStateExceptionsAttribute is obsolete + namespace System.Runtime.ExceptionServices.Tests { public class HandleProcessCorruptedStateExceptionsTests diff --git a/src/tests/JIT/RyuJIT/DoWhileBndChk.cs b/src/tests/JIT/RyuJIT/DoWhileBndChk.cs index 68f260f06b57e..9ba5a944f8ade 100644 --- a/src/tests/JIT/RyuJIT/DoWhileBndChk.cs +++ b/src/tests/JIT/RyuJIT/DoWhileBndChk.cs @@ -5,6 +5,8 @@ // // Reference: TF Bug 150041 +#pragma warning disable SYSLIB0032 // HandleProcessCorruptedStateExceptionsAttribute is obsolete + using System; using System.Runtime.ExceptionServices; From 13a2b6dedf13f23ebec97b153e27ed93ea3e7215 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Tue, 3 Aug 2021 17:04:17 -0700 Subject: [PATCH 6/9] Ecma edit for `conv.ovf..un`. (#56450) * Add a conv conformance test. * Fix Ecma description. * Fix the test. * Update docs/design/specs/Ecma-335-Augments.md Co-authored-by: Jan Kotas * Disable VN optimizations on arm64 because of the bug. * add a new chapter. * fix space * Fix format. * exclude the test on mono Co-authored-by: Jan Kotas --- docs/design/specs/Ecma-335-Augments.md | 33 +- .../Convert/TestConvertFromIntegral.cs | 1187 +++++++++++++++++ .../Convert/TestConvertFromIntegral.csproj | 24 + src/tests/issues.targets | 3 + 4 files changed, 1246 insertions(+), 1 deletion(-) create mode 100644 src/tests/JIT/IL_Conformance/Convert/TestConvertFromIntegral.cs create mode 100644 src/tests/JIT/IL_Conformance/Convert/TestConvertFromIntegral.csproj diff --git a/docs/design/specs/Ecma-335-Augments.md b/docs/design/specs/Ecma-335-Augments.md index 546a6dbc37555..6a21e31237e94 100644 --- a/docs/design/specs/Ecma-335-Augments.md +++ b/docs/design/specs/Ecma-335-Augments.md @@ -11,6 +11,7 @@ This is a list of additions and edits to be made in ECMA-335 specifications. It - [Default Interface Methods](#default-interface-methods) - [Static Interface Methods](#static-interface-methods) - [Covariant Return Types](#covariant-return-types) +- [Unsigned data conversion with overflow detection](#unsigned-data-conversion-with-overflow-detection) ## Signatures @@ -907,4 +908,34 @@ For this example, the behavior of calls on objects of various types is presented | D | B::VirtualFunction() | ERROR | A program containing type D is not valid, as B::VirtualFunction would be implemented by D::VirtualFunction which is not *covariant-return-compatible-with* (§I.8.7.1) B::VirtualFunction | " ### II.22.27 -Edit rule 12 to specify that "The method signature defined by *MethodBody* shall match those defined by *MethodDeclaration* exactly if *MethodDeclaration* defines a method on an interface or be *covariant-return-compatible-with* (§I.8.7.1) if *MethodDeclaration* represents a method on a class." \ No newline at end of file +Edit rule 12 to specify that "The method signature defined by *MethodBody* shall match those defined by *MethodDeclaration* exactly if *MethodDeclaration* defines a method on an interface or be *covariant-return-compatible-with* (§I.8.7.1) if *MethodDeclaration* represents a method on a class." + +## Unsigned data conversion with overflow detection + +`conv.ovf..un` opcode is purposed for converting a value on the stack to an integral value while treating the stack source as unsigned. Ecma does not distinguish signed and unsigned values on the stack so such opcode is needed as a complement for `conv.ovf.`. +So if the value on the stack is 4-byte size integral created by `Ldc_I4 0xFFFFFFFF` the results of different conversion opcodes will be: + +* conv.ovf.i4 -> -1 (0xFFFFFFFF) +* conv.ovf.u4 -> overflow +* conv.ovf.i4.un -> overflow +* conv.ovf.u4.un -> uint.MaxValue (0xFFFFFFFF) + +However, the source of these opcodes can be a float value and it was not clear how in such case .un should be treated. The ECMA was saying: "The item on the top of the stack is treated as an unsigned value before the conversion." but there was no definition of "treated" so the result of: + +``` +ldc.r4 -1 +conv.ovf.i4.un +``` +was ambiguous, it could treat -1 as 0xFFFFFFFF and return 0xFFFFFFFF or it could throw an overflow exception. + +### III.3.19, conv.ovf.to type.un (page 354) +(Edit 1st Description paragraph:) +Convert the value on top of the stack to the type specified in the opcode, and leave that converted +value on the top of the stack. If the value cannot be represented, an exception is thrown. + +(Edit 2nd Description paragraph:) + +Conversions from floating-point numbers to integral values truncate the number toward zero and used as-is ignoring .un suffix. The integral item +on the top of the stack is reinterpreted as an unsigned value before the conversion. +Note that integer values of less than 4 bytes are extended to int32 (not native int) on the +evaluation stack. \ No newline at end of file diff --git a/src/tests/JIT/IL_Conformance/Convert/TestConvertFromIntegral.cs b/src/tests/JIT/IL_Conformance/Convert/TestConvertFromIntegral.cs new file mode 100644 index 0000000000000..8ab686a3fb654 --- /dev/null +++ b/src/tests/JIT/IL_Conformance/Convert/TestConvertFromIntegral.cs @@ -0,0 +1,1187 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// This is conformance test for conv described in ECMA-335 Table III.8: Conversion Operations. +// It tests int32/int64/float/double as the source and sbyte/byte/short/ushort/int/uint/long/ulong +// as the dst. + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Reflection; +using System.Reflection.Emit; + +namespace TestCasts +{ + class Program + { + static int failedCount = 0; + + static readonly bool ExpectException = true; + static readonly bool DontExpectException = false; + + static readonly bool UnspecifiedBehaviour = true; + + static void GenerateTest(F from, OpCode fromOpcode, OpCode convOpcode, bool exceptionExpected, T expectedTo, bool undefined = false) where F : struct where T : struct, IEquatable + { + bool checkResult = !exceptionExpected && !undefined; + Debug.Assert(!exceptionExpected || !checkResult); + Debug.Assert(checkResult || expectedTo.Equals(default(T))); + + Type[] args = new Type[] { }; // No args. + Type returnType = typeof(T); + string name = "DynamicConvertFrom" + typeof(F).FullName + "To" + typeof(T).FullName + from.ToString() + "Op" + convOpcode.Name; + DynamicMethod dm = new DynamicMethod(name, returnType, args); + + ILGenerator generator = dm.GetILGenerator(); + + if (typeof(F) == typeof(int)) generator.Emit(fromOpcode, (int)(object)from); + else if (typeof(F) == typeof(long)) generator.Emit(fromOpcode, (long)(object)from); + else if (typeof(F) == typeof(nint)) generator.Emit(fromOpcode, (nint)(object)from); + else if (typeof(F) == typeof(float)) generator.Emit(fromOpcode, (float)(object)from); + else if (typeof(F) == typeof(double)) generator.Emit(fromOpcode, (double)(object)from); + else + { + throw new NotSupportedException(); + } + + generator.Emit(convOpcode); + generator.Emit(OpCodes.Ret); + + try + { + T res = (T)dm.Invoke(null, BindingFlags.Default, null, new object[] { }, null); + if (exceptionExpected) + { + failedCount++; + Console.WriteLine("No exception in " + name); + } + if (checkResult && !expectedTo.Equals(res)) + { + failedCount++; + Console.WriteLine("Wrong result in " + name); + } + } + catch + { + if (!exceptionExpected) + { + failedCount++; + Console.WriteLine("Not expected exception in " + name); + } + } + } + + static void TestConvertFromInt4() + { + TestConvertFromInt4ToI1(); + TestConvertFromInt4ToU1(); + TestConvertFromInt4ToI2(); + TestConvertFromInt4ToU2(); + TestConvertFromInt4ToI4(); + TestConvertFromInt4ToU4(); + TestConvertFromInt4ToI8(); + TestConvertFromInt4ToU8(); + } + + static void TestConvertFromInt4ToI1() + { + OpCode sourceOp = OpCodes.Ldc_I4; + + OpCode convNoOvf = OpCodes.Conv_I1; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(sbyte.MaxValue, sourceOp, convNoOvf, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convNoOvf, DontExpectException, sbyte.MinValue); + GenerateTest(byte.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(byte.MinValue, sourceOp, convNoOvf, DontExpectException, (sbyte)byte.MinValue); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + + OpCode convOvf = OpCodes.Conv_Ovf_I1; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(sbyte.MaxValue, sourceOp, convOvf, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvf, DontExpectException, sbyte.MinValue); + GenerateTest(byte.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(byte.MinValue, sourceOp, convOvf, DontExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I1_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(sbyte.MaxValue, sourceOp, convOvfUn, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(byte.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(byte.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt4ToU1() + { + OpCode sourceOp = OpCodes.Ldc_I4; + + OpCode convNoOvf = OpCodes.Conv_U1; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, byte.MaxValue); + GenerateTest(sbyte.MaxValue, sourceOp, convNoOvf, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convNoOvf, DontExpectException, (byte)sbyte.MaxValue + 1); + GenerateTest(byte.MaxValue, sourceOp, convNoOvf, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convNoOvf, DontExpectException, byte.MinValue); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, byte.MaxValue); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + + OpCode convOvf = OpCodes.Conv_Ovf_U1; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(sbyte.MaxValue, sourceOp, convOvf, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(byte.MaxValue, sourceOp, convOvf, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convOvf, DontExpectException, byte.MinValue); + GenerateTest(int.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U1_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(sbyte.MaxValue, sourceOp, convOvfUn, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(byte.MaxValue, sourceOp, convOvfUn, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convOvfUn, DontExpectException, byte.MinValue); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt4ToI2() + { + OpCode sourceOp = OpCodes.Ldc_I4; + + OpCode convNoOvf = OpCodes.Conv_I2; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(short.MaxValue, sourceOp, convNoOvf, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convNoOvf, DontExpectException, short.MinValue); + GenerateTest(ushort.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(ushort.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + + OpCode convOvf = OpCodes.Conv_Ovf_I2; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(short.MaxValue, sourceOp, convOvf, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvf, DontExpectException, short.MinValue); + GenerateTest(ushort.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(ushort.MinValue, sourceOp, convOvf, DontExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I2_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(short.MaxValue, sourceOp, convOvfUn, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(ushort.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(ushort.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt4ToU2() + { + OpCode sourceOp = OpCodes.Ldc_I4; + + OpCode convNoOvf = OpCodes.Conv_U2; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, ushort.MaxValue); + GenerateTest(short.MaxValue, sourceOp, convNoOvf, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convNoOvf, DontExpectException, (short)short.MaxValue + 1); + GenerateTest(ushort.MaxValue, sourceOp, convNoOvf, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convNoOvf, DontExpectException, ushort.MinValue); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, ushort.MaxValue); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + + OpCode convOvf = OpCodes.Conv_Ovf_U2; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(short.MaxValue, sourceOp, convOvf, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(ushort.MaxValue, sourceOp, convOvf, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convOvf, DontExpectException, ushort.MinValue); + GenerateTest(int.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U2_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(short.MaxValue, sourceOp, convOvfUn, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(ushort.MaxValue, sourceOp, convOvfUn, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convOvfUn, DontExpectException, ushort.MinValue); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt4ToI4() + { + OpCode sourceOp = OpCodes.Ldc_I4; + + OpCode convNoOvf = OpCodes.Conv_I4; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, int.MinValue); + + OpCode convOvf = OpCodes.Conv_Ovf_I4; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(int.MaxValue, sourceOp, convOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvf, DontExpectException, int.MinValue); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I4_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt4ToU4() + { + OpCode sourceOp = OpCodes.Ldc_I4; + + OpCode convNoOvf = OpCodes.Conv_U4; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, uint.MaxValue); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, (uint)int.MaxValue + 1); + + OpCode convOvf = OpCodes.Conv_Ovf_U4; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U4_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, DontExpectException, uint.MaxValue); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvfUn, DontExpectException, (uint)int.MaxValue + 1); + } + + static void TestConvertFromInt4ToI8() + { + OpCode sourceOp = OpCodes.Ldc_I4; + + OpCode convNoOvf = OpCodes.Conv_I8; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, int.MinValue); + + OpCode convOvf = OpCodes.Conv_Ovf_I8; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(int.MaxValue, sourceOp, convOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvf, DontExpectException, int.MinValue); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I8_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, DontExpectException, uint.MaxValue); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvfUn, DontExpectException, (long)int.MaxValue + 1); + } + + static void TestConvertFromInt4ToU8() + { + OpCode sourceOp = OpCodes.Ldc_I4; + + OpCode convNoOvf = OpCodes.Conv_U8; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, uint.MaxValue); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, (ulong)int.MaxValue + 1); + + OpCode convOvf = OpCodes.Conv_Ovf_U8; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U8_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, DontExpectException, uint.MaxValue); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvfUn, DontExpectException, (ulong)int.MaxValue + 1); + } + + static void TestConvertFromInt8() + { + TestConvertFromInt8ToI1(); + TestConvertFromInt8ToU1(); + TestConvertFromInt8ToI2(); + TestConvertFromInt8ToU2(); + TestConvertFromInt8ToI4(); + TestConvertFromInt8ToU4(); + TestConvertFromInt8ToI8(); + TestConvertFromInt8ToU8(); + } + + static void TestConvertFromInt8ToI1() + { + OpCode sourceOp = OpCodes.Ldc_I8; + + OpCode convNoOvf = OpCodes.Conv_I1; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(sbyte.MaxValue, sourceOp, convNoOvf, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convNoOvf, DontExpectException, sbyte.MinValue); + GenerateTest(byte.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(byte.MinValue, sourceOp, convNoOvf, DontExpectException, (sbyte)byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + + OpCode convOvf = OpCodes.Conv_Ovf_I1; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(sbyte.MaxValue, sourceOp, convOvf, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvf, DontExpectException, sbyte.MinValue); + GenerateTest(byte.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(byte.MinValue, sourceOp, convOvf, DontExpectException, (sbyte)byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I1_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(sbyte.MaxValue, sourceOp, convOvfUn, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(byte.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(byte.MinValue, sourceOp, convOvfUn, DontExpectException, (sbyte)byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt8ToU1() + { + OpCode sourceOp = OpCodes.Ldc_I8; + + OpCode convNoOvf = OpCodes.Conv_U1; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, byte.MaxValue); + GenerateTest(sbyte.MaxValue, sourceOp, convNoOvf, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convNoOvf, DontExpectException, (byte)sbyte.MaxValue + 1); + GenerateTest(byte.MaxValue, sourceOp, convNoOvf, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convNoOvf, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, byte.MaxValue); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + + OpCode convOvf = OpCodes.Conv_Ovf_U1; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(sbyte.MaxValue, sourceOp, convOvf, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(byte.MaxValue, sourceOp, convOvf, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convOvf, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U1_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(sbyte.MaxValue, sourceOp, convOvfUn, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(byte.MaxValue, sourceOp, convOvfUn, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convOvfUn, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt8ToI2() + { + OpCode sourceOp = OpCodes.Ldc_I8; + + OpCode convNoOvf = OpCodes.Conv_I2; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(short.MaxValue, sourceOp, convNoOvf, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convNoOvf, DontExpectException, short.MinValue); + GenerateTest(ushort.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(ushort.MinValue, sourceOp, convNoOvf, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + + OpCode convOvf = OpCodes.Conv_Ovf_I2; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(short.MaxValue, sourceOp, convOvf, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvf, DontExpectException, short.MinValue); + GenerateTest(ushort.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(ushort.MinValue, sourceOp, convOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I2_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(short.MaxValue, sourceOp, convOvfUn, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(ushort.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(ushort.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt8ToU2() + { + OpCode sourceOp = OpCodes.Ldc_I8; + + OpCode convNoOvf = OpCodes.Conv_U2; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, ushort.MaxValue); + GenerateTest(short.MaxValue, sourceOp, convNoOvf, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convNoOvf, DontExpectException, (ushort)short.MaxValue + 1); + GenerateTest(ushort.MaxValue, sourceOp, convNoOvf, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convNoOvf, DontExpectException, ushort.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, ushort.MaxValue); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + + OpCode convOvf = OpCodes.Conv_Ovf_U2; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(short.MaxValue, sourceOp, convOvf, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(ushort.MaxValue, sourceOp, convOvf, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convOvf, DontExpectException, ushort.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U2_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(short.MaxValue, sourceOp, convOvfUn, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(ushort.MaxValue, sourceOp, convOvfUn, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convOvfUn, DontExpectException, ushort.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt8ToI4() + { + OpCode sourceOp = OpCodes.Ldc_I8; + + OpCode convNoOvf = OpCodes.Conv_I4; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, int.MinValue); + GenerateTest(uint.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(uint.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + + OpCode convOvf = OpCodes.Conv_Ovf_I4; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(int.MaxValue, sourceOp, convOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvf, DontExpectException, int.MinValue); + GenerateTest(uint.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(uint.MinValue, sourceOp, convOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I4_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(uint.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(uint.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt8ToU4() + { + OpCode sourceOp = OpCodes.Ldc_I8; + + OpCode convNoOvf = OpCodes.Conv_U4; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, uint.MaxValue); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, (uint)int.MaxValue + 1); + GenerateTest(uint.MaxValue, sourceOp, convNoOvf, DontExpectException, uint.MaxValue); + GenerateTest(uint.MinValue, sourceOp, convNoOvf, DontExpectException, uint.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, uint.MaxValue); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + + OpCode convOvf = OpCodes.Conv_Ovf_U4; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(uint.MaxValue, sourceOp, convOvf, DontExpectException, uint.MaxValue); + GenerateTest(uint.MinValue, sourceOp, convOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U4_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(uint.MaxValue, sourceOp, convOvfUn, DontExpectException, uint.MaxValue); + GenerateTest(uint.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt8ToI8() + { + OpCode sourceOp = OpCodes.Ldc_I8; + + OpCode convNoOvf = OpCodes.Conv_I8; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, int.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, long.MaxValue); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, long.MinValue); + + OpCode convOvf = OpCodes.Conv_Ovf_I8; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(int.MaxValue, sourceOp, convOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvf, DontExpectException, int.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvf, DontExpectException, long.MaxValue); + GenerateTest(long.MinValue, sourceOp, convOvf, DontExpectException, long.MinValue); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I8_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, DontExpectException, long.MaxValue); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromInt8ToU8() + { + OpCode sourceOp = OpCodes.Ldc_I8; + + OpCode convNoOvf = OpCodes.Conv_U8; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, ulong.MaxValue); + GenerateTest(int.MaxValue, sourceOp, convNoOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, 0xffffffff80000000UL); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, long.MaxValue); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, (ulong)long.MaxValue + 1); + + OpCode convOvf = OpCodes.Conv_Ovf_U8; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MaxValue, sourceOp, convOvf, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvf, DontExpectException, long.MaxValue); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U8_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, DontExpectException, ulong.MaxValue); + GenerateTest(int.MaxValue, sourceOp, convOvfUn, DontExpectException, int.MaxValue); + GenerateTest(int.MinValue, sourceOp, convOvfUn, DontExpectException, ulong.MaxValue - int.MaxValue); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, DontExpectException, long.MaxValue); + GenerateTest(long.MinValue, sourceOp, convOvfUn, DontExpectException, (ulong)long.MaxValue + 1); + } + + + static void TestConvertFromFloat() + { + TestConvertFromFloatToI1(); + TestConvertFromFloatToU1(); + TestConvertFromFloatToI2(); + TestConvertFromFloatToU2(); + TestConvertFromFloatToI4(); + TestConvertFromFloatToU4(); + TestConvertFromFloatToI8(); + TestConvertFromFloatToU8(); + } + + static void TestConvertFromFloatToI1() + { + OpCode sourceOp = OpCodes.Ldc_R4; + + OpCode convNoOvf = OpCodes.Conv_I1; + GenerateTest(1F, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(1.1F, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1.1F, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(sbyte.MaxValue, sourceOp, convNoOvf, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convNoOvf, DontExpectException, sbyte.MinValue); + GenerateTest(byte.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(byte.MinValue, sourceOp, convNoOvf, DontExpectException, (sbyte)byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_I1; + GenerateTest(1F, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(1.1F, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1.1F, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(sbyte.MaxValue, sourceOp, convOvf, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvf, DontExpectException, sbyte.MinValue); + GenerateTest(byte.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(byte.MinValue, sourceOp, convOvf, DontExpectException, (sbyte)byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I1_Un; + GenerateTest(1F, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convOvfUn, DontExpectException, -1); + GenerateTest(1.1F, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1.1F, sourceOp, convOvfUn, DontExpectException, -1); + GenerateTest(sbyte.MaxValue, sourceOp, convOvfUn, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvfUn, DontExpectException, sbyte.MinValue); + GenerateTest(byte.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(byte.MinValue, sourceOp, convOvfUn, DontExpectException, (sbyte)byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromFloatToU1() + { + OpCode sourceOp = OpCodes.Ldc_R4; + + OpCode convNoOvf = OpCodes.Conv_U1; + GenerateTest(1F, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(sbyte.MaxValue, sourceOp, convNoOvf, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(byte.MaxValue, sourceOp, convNoOvf, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convNoOvf, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_U1; + GenerateTest(1F, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(1.9F, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convOvf, ExpectException, 0); + GenerateTest(sbyte.MaxValue, sourceOp, convOvf, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(byte.MaxValue, sourceOp, convOvf, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convOvf, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + + OpCode convOvfUn = OpCodes.Conv_Ovf_U1_Un; + GenerateTest(1F, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(2.2F, sourceOp, convOvfUn, DontExpectException, 2); + GenerateTest(-1F, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(sbyte.MaxValue, sourceOp, convOvfUn, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(byte.MaxValue, sourceOp, convOvfUn, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convOvfUn, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromFloatToI2() + { + OpCode sourceOp = OpCodes.Ldc_R4; + + OpCode convNoOvf = OpCodes.Conv_I2; + GenerateTest(1F, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(short.MaxValue, sourceOp, convNoOvf, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convNoOvf, DontExpectException, short.MinValue); + GenerateTest(ushort.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(ushort.MinValue, sourceOp, convNoOvf, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_I2; + GenerateTest(1F, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(1.2F, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(-1.8F, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(short.MaxValue, sourceOp, convOvf, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvf, DontExpectException, short.MinValue); + GenerateTest(ushort.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(ushort.MinValue, sourceOp, convOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I2_Un; + GenerateTest(1F, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(1.5F, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1.5F, sourceOp, convOvfUn, DontExpectException, -1); + GenerateTest(short.MaxValue, sourceOp, convOvfUn, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvfUn, DontExpectException, short.MinValue); + GenerateTest(ushort.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(ushort.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromFloatToU2() + { + OpCode sourceOp = OpCodes.Ldc_R4; + + OpCode convNoOvf = OpCodes.Conv_U2; + GenerateTest(1F, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(3.9F, sourceOp, convNoOvf, DontExpectException, 3); + GenerateTest(-1F, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + GenerateTest(short.MaxValue, sourceOp, convNoOvf, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(ushort.MaxValue, sourceOp, convNoOvf, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convNoOvf, DontExpectException, ushort.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_U2; + GenerateTest(1F, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(1.3F, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convOvf, ExpectException, 0); + GenerateTest(short.MaxValue, sourceOp, convOvf, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(ushort.MaxValue, sourceOp, convOvf, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convOvf, DontExpectException, ushort.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U2_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(short.MaxValue, sourceOp, convOvfUn, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(ushort.MaxValue, sourceOp, convOvfUn, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convOvfUn, DontExpectException, ushort.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromFloatToI4() + { + OpCode sourceOp = OpCodes.Ldc_R4; + + OpCode convNoOvf = OpCodes.Conv_I4; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, int.MinValue); + GenerateTest(uint.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(uint.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I4_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convOvfUn, DontExpectException, int.MinValue); + GenerateTest(uint.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(uint.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromFloatToU4() + { + OpCode sourceOp = OpCodes.Ldc_R4; + + OpCode convNoOvf = OpCodes.Conv_U4; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(uint.MinValue, sourceOp, convNoOvf, DontExpectException, uint.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_U4; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(uint.MinValue, sourceOp, convOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U4_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(uint.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromFloatToI8() + { + OpCode sourceOp = OpCodes.Ldc_R4; + + OpCode convNoOvf = OpCodes.Conv_I8; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, int.MinValue); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, long.MinValue); + + OpCode convOvf = OpCodes.Conv_Ovf_I8; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convOvf, DontExpectException, int.MinValue); + GenerateTest(long.MinValue, sourceOp, convOvf, DontExpectException, long.MinValue); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I8_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convOvfUn, DontExpectException, int.MinValue); + GenerateTest(long.MinValue, sourceOp, convOvfUn, DontExpectException, long.MinValue); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromFloatToU8() + { + OpCode sourceOp = OpCodes.Ldc_R4; + + OpCode convNoOvf = OpCodes.Conv_U8; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_U8; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U8_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromDouble() + { + TestConvertFromDoubleToI1(); + TestConvertFromDoubleToU1(); + TestConvertFromDoubleToI2(); + TestConvertFromDoubleToU2(); + TestConvertFromDoubleToI4(); + TestConvertFromDoubleToU4(); + TestConvertFromDoubleToI8(); + TestConvertFromDoubleToU8(); + } + + static void TestConvertFromDoubleToI1() + { + OpCode sourceOp = OpCodes.Ldc_R8; + + OpCode convNoOvf = OpCodes.Conv_I1; + GenerateTest(1F, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(1.1F, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1.1F, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(sbyte.MaxValue, sourceOp, convNoOvf, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convNoOvf, DontExpectException, sbyte.MinValue); + GenerateTest(byte.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(byte.MinValue, sourceOp, convNoOvf, DontExpectException, (sbyte)byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_I1; + GenerateTest(1F, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(1.1F, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1.1F, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(sbyte.MaxValue, sourceOp, convOvf, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvf, DontExpectException, sbyte.MinValue); + GenerateTest(byte.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(byte.MinValue, sourceOp, convOvf, DontExpectException, (sbyte)byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I1_Un; + GenerateTest(1F, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1F, sourceOp, convOvfUn, DontExpectException, -1); + GenerateTest(1.1F, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1.1F, sourceOp, convOvfUn, DontExpectException, -1); + GenerateTest(sbyte.MaxValue, sourceOp, convOvfUn, DontExpectException, sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvfUn, DontExpectException, sbyte.MinValue); + GenerateTest(byte.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(byte.MinValue, sourceOp, convOvfUn, DontExpectException, (sbyte)byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromDoubleToU1() + { + OpCode sourceOp = OpCodes.Ldc_R8; + + OpCode convNoOvf = OpCodes.Conv_U1; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(sbyte.MaxValue, sourceOp, convNoOvf, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(byte.MaxValue, sourceOp, convNoOvf, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convNoOvf, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_U1; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(sbyte.MaxValue, sourceOp, convOvf, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(byte.MaxValue, sourceOp, convOvf, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convOvf, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U1_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(sbyte.MaxValue, sourceOp, convOvfUn, DontExpectException, (byte)sbyte.MaxValue); + GenerateTest(sbyte.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(byte.MaxValue, sourceOp, convOvfUn, DontExpectException, byte.MaxValue); + GenerateTest(byte.MinValue, sourceOp, convOvfUn, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromDoubleToI2() + { + OpCode sourceOp = OpCodes.Ldc_R8; + + OpCode convNoOvf = OpCodes.Conv_I2; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(short.MaxValue, sourceOp, convNoOvf, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convNoOvf, DontExpectException, short.MinValue); + GenerateTest(ushort.MaxValue, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(ushort.MinValue, sourceOp, convNoOvf, DontExpectException, byte.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_I2; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(short.MaxValue, sourceOp, convOvf, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvf, DontExpectException, short.MinValue); + GenerateTest(ushort.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(ushort.MinValue, sourceOp, convOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I2_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, DontExpectException, -1); + GenerateTest(short.MaxValue, sourceOp, convOvfUn, DontExpectException, short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvfUn, DontExpectException, short.MinValue); + GenerateTest(ushort.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(ushort.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromDoubleToU2() + { + OpCode sourceOp = OpCodes.Ldc_R8; + + OpCode convNoOvf = OpCodes.Conv_U2; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(short.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(short.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(ushort.MaxValue, sourceOp, convNoOvf, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convNoOvf, DontExpectException, ushort.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_U2; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(short.MaxValue, sourceOp, convOvf, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(ushort.MaxValue, sourceOp, convOvf, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convOvf, DontExpectException, ushort.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U2_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(short.MaxValue, sourceOp, convOvfUn, DontExpectException, (ushort)short.MaxValue); + GenerateTest(short.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(ushort.MaxValue, sourceOp, convOvfUn, DontExpectException, ushort.MaxValue); + GenerateTest(ushort.MinValue, sourceOp, convOvfUn, DontExpectException, ushort.MinValue); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromDoubleToI4() + { + OpCode sourceOp = OpCodes.Ldc_R8; + + OpCode convNoOvf = OpCodes.Conv_I4; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, int.MinValue); + GenerateTest(uint.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(uint.MinValue, sourceOp, convNoOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_I4; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convOvf, DontExpectException, int.MinValue); + GenerateTest(uint.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(uint.MinValue, sourceOp, convOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I4_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convOvfUn, DontExpectException, int.MinValue); + GenerateTest(uint.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(uint.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromDoubleToU4() + { + OpCode sourceOp = OpCodes.Ldc_R8; + + OpCode convNoOvf = OpCodes.Conv_U4; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(uint.MinValue, sourceOp, convNoOvf, DontExpectException, uint.MinValue); + GenerateTest(long.MaxValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_U4; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(uint.MinValue, sourceOp, convOvf, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U4_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(uint.MinValue, sourceOp, convOvfUn, DontExpectException, 0); + GenerateTest(long.MaxValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromDoubleToI8() + { + OpCode sourceOp = OpCodes.Ldc_R8; + + OpCode convNoOvf = OpCodes.Conv_I8; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, int.MinValue); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, long.MinValue); + + OpCode convOvf = OpCodes.Conv_Ovf_I8; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convOvf, DontExpectException, int.MinValue); + GenerateTest(long.MinValue, sourceOp, convOvf, DontExpectException, long.MinValue); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_I8_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, DontExpectException, -1); + GenerateTest(int.MinValue, sourceOp, convOvfUn, DontExpectException, int.MinValue); + GenerateTest(long.MinValue, sourceOp, convOvfUn, DontExpectException, long.MinValue); + GenerateTest(-9E+18, sourceOp, convOvfUn, DontExpectException, (long)-9E+18); + GenerateTest(9E+18, sourceOp, convOvfUn, DontExpectException, (long)9E+18); + GenerateTest(18E+18, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static void TestConvertFromDoubleToU8() + { + OpCode sourceOp = OpCodes.Ldc_R8; + + OpCode convNoOvf = OpCodes.Conv_U8; + GenerateTest(1, sourceOp, convNoOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(int.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + GenerateTest(long.MinValue, sourceOp, convNoOvf, DontExpectException, 0, UnspecifiedBehaviour); + + OpCode convOvf = OpCodes.Conv_Ovf_U8; + GenerateTest(1, sourceOp, convOvf, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvf, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvf, ExpectException, 0); + GenerateTest(-9E+18, sourceOp, convOvf, ExpectException, 0); + GenerateTest(9E+18, sourceOp, convOvf, DontExpectException, (ulong)9E+18); + GenerateTest(18E+18, sourceOp, convOvf, DontExpectException, (ulong)18E+18); + GenerateTest(Single.NaN, sourceOp, convOvf, ExpectException, 0); + + OpCode convOvfUn = OpCodes.Conv_Ovf_U8_Un; + GenerateTest(1, sourceOp, convOvfUn, DontExpectException, 1); + GenerateTest(-1, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(int.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(long.MinValue, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(-9E+18, sourceOp, convOvfUn, ExpectException, 0); + GenerateTest(9E+18, sourceOp, convOvfUn, DontExpectException, (ulong)9E+18); + GenerateTest(18E+18, sourceOp, convOvfUn, DontExpectException, (ulong)18E+18); + GenerateTest(Single.NaN, sourceOp, convOvfUn, ExpectException, 0); + } + + static int Main(string[] args) + { + TestConvertFromInt4(); + TestConvertFromInt8(); + TestConvertFromFloat(); + TestConvertFromDouble(); + if (failedCount > 0) + { + Console.WriteLine("The number of failed tests: " + failedCount); + return 101; + } + else + { + Console.WriteLine("All tests passed"); + return 100; + } + + } + } +} diff --git a/src/tests/JIT/IL_Conformance/Convert/TestConvertFromIntegral.csproj b/src/tests/JIT/IL_Conformance/Convert/TestConvertFromIntegral.csproj new file mode 100644 index 0000000000000..0d098d9ebdad5 --- /dev/null +++ b/src/tests/JIT/IL_Conformance/Convert/TestConvertFromIntegral.csproj @@ -0,0 +1,24 @@ + + + Exe + 1 + + + None + True + + + + + + + + + + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index d121409c54bd3..09120056761c9 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1652,6 +1652,9 @@ Tests coreclr JIT's debug poisoning of address taken variables + + https://github.com/dotnet/runtime/issues/56784 + From 2bdf376f9e060770e2c7bfdd2280ed0ac18688a2 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 3 Aug 2021 21:37:34 -0400 Subject: [PATCH 7/9] [mono][wasm] Allow setting env variables with '=' characters in the test runner. (#56802) --- src/mono/wasm/runtime-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index e661a5423a0d2..6796330a98012 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -168,9 +168,9 @@ while (args !== undefined && args.length > 0) { } else if (args [0].startsWith ("--setenv=")) { var arg = args [0].substring ("--setenv=".length); var parts = arg.split ('='); - if (parts.length != 2) + if (parts.length < 2) fail_exec ("Error: malformed argument: '" + args [0]); - setenv [parts [0]] = parts [1]; + setenv [parts [0]] = arg.substring (parts [0].length + 1); args = args.slice (1); } else if (args [0].startsWith ("--runtime-arg=")) { var arg = args [0].substring ("--runtime-arg=".length); From 63a304ad99d15d4882839a9c08784464683eadd1 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Tue, 3 Aug 2021 22:44:23 -0300 Subject: [PATCH 8/9] [debugger] Fix debugger.break behavior (#56788) * Fix debugger.break behavior. * Fix line number of other tests that uses Debugger.Break. --- src/mono/mono/mini/interp/interp.c | 1 + .../DebuggerTestSuite/BreakpointTests.cs | 41 ++++++++++++++++--- .../DebuggerTestSuite/GetPropertiesTests.cs | 2 +- .../tests/debugger-test/debugger-test2.cs | 4 ++ 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 44d1c70b396bc..d43b388f1e6f3 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -3297,6 +3297,7 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs MINT_IN_BREAK; MINT_IN_CASE(MINT_BREAK) ++ip; + SAVE_INTERP_STATE (frame); do_debugger_tramp (mono_component_debugger ()->user_break, frame); MINT_IN_BREAK; MINT_IN_CASE(MINT_BREAKPOINT) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs index ed5d59e7ef572..db5fbf34b40c2 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs @@ -259,8 +259,37 @@ public async Task BreakOnDebuggerBreak() { await EvaluateAndCheck( "window.setTimeout(function() { invoke_static_method_async('[debugger-test] UserBreak:BreakOnDebuggerBreakCommand'); }, 1);", - "dotnet://debugger-test.dll/debugger-test2.cs", 58, 4, - "BreakOnDebuggerBreakCommand"); + "dotnet://debugger-test.dll/debugger-test2.cs", 58, 8, + "BreakOnDebuggerBreakCommand", + locals_fn: (locals) => + { + CheckNumber(locals, "a", 10); + } + ); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test2.cs", 59, 8, "BreakOnDebuggerBreakCommand", + locals_fn: (locals) => + { + CheckNumber(locals, "a", 10); + } + ); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test2.cs", 60, 8, "BreakOnDebuggerBreakCommand", + locals_fn: (locals) => + { + CheckNumber(locals, "a", 20); + } + ); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test2.cs", 61, 8, "BreakOnDebuggerBreakCommand", + locals_fn: (locals) => + { + CheckNumber(locals, "a", 50); + } + ); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test2.cs", 62, 4, "BreakOnDebuggerBreakCommand", + locals_fn: (locals) => + { + CheckNumber(locals, "a", 100); + } + ); } [Fact] @@ -297,10 +326,10 @@ public async Task DebugHotReloadMethodChangedUserBreak() "MethodBody1", "StaticMethod1"); var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); CheckNumber(locals, "a", 10); - pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 14, 8, "StaticMethod1"); + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 12, 16, "StaticMethod1"); locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); CheckNumber(locals, "b", 15); - pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 14, 8, "StaticMethod1"); + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 12, 12, "StaticMethod1"); locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); CheckBool(locals, "c", true); } @@ -315,10 +344,10 @@ public async Task DebugHotReloadMethodUnchanged() "MethodBody2", "StaticMethod1"); var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); CheckNumber(locals, "a", 10); - pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 23, 8, "StaticMethod1"); + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 21, 12, "StaticMethod1"); locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); CheckNumber(locals, "a", 10); - pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 23, 8, "StaticMethod1"); + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 21, 12, "StaticMethod1"); locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); CheckNumber(locals, "a", 10); } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/GetPropertiesTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/GetPropertiesTests.cs index 51064a7bf3ff6..da971017a35ad 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/GetPropertiesTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/GetPropertiesTests.cs @@ -340,7 +340,7 @@ public async Task GetObjectValueWithInheritance() { var pause_location = await EvaluateAndCheck( "window.setTimeout(function() { invoke_static_method('[debugger-test] TestChild:TestWatchWithInheritance'); }, 1);", - "dotnet://debugger-test.dll/debugger-test2.cs", 122, 4, + "dotnet://debugger-test.dll/debugger-test2.cs", 125, 8, "TestWatchWithInheritance"); var frame_id = pause_location["callFrames"][0]["callFrameId"].Value(); var frame_locals = await GetProperties(frame_id); diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-test2.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-test2.cs index 2a5d525392fc9..8cfb301ff7e51 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-test2.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-test2.cs @@ -55,7 +55,11 @@ public static void Types() public class UserBreak { public static void BreakOnDebuggerBreakCommand() { + int a = 10; Debugger.Break(); + a = 20; + a = 50; + a = 100; } } From 55cea645dc52a6f7d5e5105846ec49bc7fda2a40 Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Tue, 3 Aug 2021 19:01:45 -0700 Subject: [PATCH 9/9] disable token info in traces. (#56780) Though token+offset is useful for certain scenarios, they might not be usable for majority of scenarios. So disabling them by default. --- .../src/System/LocalAppContextSwitches.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/LocalAppContextSwitches.cs b/src/libraries/System.Private.CoreLib/src/System/LocalAppContextSwitches.cs index ed450d7494369..37e2265f5f8f9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/LocalAppContextSwitches.cs +++ b/src/libraries/System.Private.CoreLib/src/System/LocalAppContextSwitches.cs @@ -54,7 +54,8 @@ private static bool GetDefaultShowILOffsetSetting() if (s_showILOffset < 0) return false; if (s_showILOffset > 0) return true; - bool isSwitchEnabled = AppContextConfigHelper.GetBooleanConfig("Switch.System.Diagnostics.StackTrace.ShowILOffsets", true); + // Disabled by default. + bool isSwitchEnabled = AppContextConfigHelper.GetBooleanConfig("Switch.System.Diagnostics.StackTrace.ShowILOffsets", false); s_showILOffset = isSwitchEnabled ? 1 : -1; return isSwitchEnabled;