diff options
author | Samuel Arzt <arzt.samuel@live.de> | 2017-08-28 16:46:27 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-08-28 16:46:27 +0300 |
commit | 42248efca984e129ab782777c9a57c7314ccdcf6 (patch) | |
tree | d38ec9045f92fce91b9175d19f5dddac5bf6fa77 /src/ILVerify | |
parent | 5138679dba78ce2807d606fd3ab1babea904785b (diff) |
[ILVerify] Fix for issue #4357 and #4358. (#4402)
* Added testcases for issue 4357 and 4358.
* Fixed ILImporter calling ImportStoreElement with Int32 instead of Int64 for i8.
* Added methods to get verifcation, intermediate and reduced type.
* Fix for issue 4357.
* Fix for issue #4358.
Diffstat (limited to 'src/ILVerify')
-rw-r--r-- | src/ILVerify/src/ILImporter.StackValue.cs | 90 | ||||
-rw-r--r-- | src/ILVerify/src/ILImporter.Verify.cs | 7 | ||||
-rw-r--r-- | src/ILVerify/tests/ILTests/ArrayTests.il | 92 | ||||
-rw-r--r-- | src/ILVerify/tests/ILTests/LoadStoreIndirectTest.il | 82 |
4 files changed, 249 insertions, 22 deletions
diff --git a/src/ILVerify/src/ILImporter.StackValue.cs b/src/ILVerify/src/ILImporter.StackValue.cs index ba58bec19..096c5fcdc 100644 --- a/src/ILVerify/src/ILImporter.StackValue.cs +++ b/src/ILVerify/src/ILImporter.StackValue.cs @@ -165,39 +165,91 @@ namespace Internal.IL partial class ILImporter { - static TypeFlags GetReducedTypeCategory(TypeDesc type) + /// <summary> + /// Returns the reduced type as defined in the ECMA-335 standard (I.8.7). + /// </summary> + public static TypeDesc GetReducedType(TypeDesc type) { - var category = type.Category; + if (type == null) + return null; - switch (type.Category) + var category = type.UnderlyingType.Category; + + switch (category) + { + case TypeFlags.Byte: + return type.Context.GetWellKnownType(WellKnownType.SByte); + case TypeFlags.UInt16: + return type.Context.GetWellKnownType(WellKnownType.Int16); + case TypeFlags.UInt32: + return type.Context.GetWellKnownType(WellKnownType.Int32); + case TypeFlags.UInt64: + return type.Context.GetWellKnownType(WellKnownType.Int64); + case TypeFlags.UIntPtr: + return type.Context.GetWellKnownType(WellKnownType.IntPtr); + + default: + return type.UnderlyingType; //Reduced type is type itself + } + } + + /// <summary> + /// Returns the "verification type" based on the definition in the ECMA-335 standard (I.8.7). + /// </summary> + public static TypeDesc GetVerificationType(TypeDesc type) + { + if (type == null) + return null; + + if (type.IsByRef) { - case TypeFlags.Byte: return TypeFlags.SByte; - case TypeFlags.UInt16: return TypeFlags.Int16; - case TypeFlags.UInt32: return TypeFlags.Int32; - case TypeFlags.UInt64: return TypeFlags.Int64; - case TypeFlags.UIntPtr: return TypeFlags.IntPtr; + var parameterVerificationType = GetVerificationType(type.GetParameterType()); + return type.Context.GetByRefType(parameterVerificationType); + } + else + { + var reducedType = GetReducedType(type); + switch (reducedType.Category) + { + case TypeFlags.Boolean: + return type.Context.GetWellKnownType(WellKnownType.SByte); + + case TypeFlags.Char: + return type.Context.GetWellKnownType(WellKnownType.Int16); + + default: + return reducedType; // Verification type is reduced type + } + } + } + /// <summary> + /// Returns the "intermediate type" based on the definition in the ECMA-335 standard (I.8.7). + /// </summary> + public static TypeDesc GetIntermediateType(TypeDesc type) + { + var verificationType = GetVerificationType(type); + + if (verificationType == null) + return null; + + switch (verificationType.Category) + { case TypeFlags.SByte: case TypeFlags.Int16: case TypeFlags.Int32: - case TypeFlags.Int64: - case TypeFlags.IntPtr: - case TypeFlags.Boolean: - case TypeFlags.Char: + return type.Context.GetWellKnownType(WellKnownType.Int32); case TypeFlags.Single: case TypeFlags.Double: - return category; + return type.Context.GetWellKnownType(WellKnownType.Double); + default: + return verificationType; } - - return TypeFlags.Unknown; } static bool IsSameReducedType(TypeDesc src, TypeDesc dst) { - var srcCategory = GetReducedTypeCategory(src); - if (srcCategory == TypeFlags.Unknown) - return false; - return srcCategory == GetReducedTypeCategory(dst); + return GetReducedType(src) == GetReducedType(dst); } bool IsAssignable(TypeDesc src, TypeDesc dst, bool allowSizeEquivalence = false) diff --git a/src/ILVerify/src/ILImporter.Verify.cs b/src/ILVerify/src/ILImporter.Verify.cs index 8d47f5d46..a0908ee76 100644 --- a/src/ILVerify/src/ILImporter.Verify.cs +++ b/src/ILVerify/src/ILImporter.Verify.cs @@ -1335,7 +1335,7 @@ namespace Internal.IL } else { - CheckIsAssignable(address.Type, type); + CheckIsAssignable(GetVerificationType(address.Type), GetVerificationType(type)); } Push(StackValue.CreateFromType(type)); } @@ -1480,7 +1480,7 @@ namespace Internal.IL if (elementType != null) { - CheckIsArrayElementCompatibleWith(actualElementType, elementType); + CheckIsArrayElementCompatibleWith(GetVerificationType(actualElementType), elementType); } else { @@ -1512,7 +1512,7 @@ namespace Internal.IL if (elementType != null) { - CheckIsArrayElementCompatibleWith(actualElementType, elementType); + CheckIsArrayElementCompatibleWith(elementType, GetVerificationType(actualElementType)); } else { @@ -1523,6 +1523,7 @@ namespace Internal.IL if (elementType != null) { + // TODO: Change to CheckIsArrayElementCompatibleWith for two intermediate types CheckIsAssignable(value, StackValue.CreateFromType(elementType)); } } diff --git a/src/ILVerify/tests/ILTests/ArrayTests.il b/src/ILVerify/tests/ILTests/ArrayTests.il new file mode 100644 index 000000000..7f4cb903a --- /dev/null +++ b/src/ILVerify/tests/ILTests/ArrayTests.il @@ -0,0 +1,92 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Runtime +{ +} + +.assembly ArrayTests +{ +} + +.class public auto ansi beforefieldinit ArrayTestsType + extends [System.Runtime]System.Object +{ + + .method public hidebysig instance void StoreElement.Int8IntoBoolArray_Valid() cil managed + { + // bool[] a = new bool[]; + // a[0] = true; + + ldc.i4.1 + newarr [System.Runtime]System.Boolean + ldc.i4.0 + ldc.i4.1 + stelem.i1 + ret + } + + .method public hidebysig instance void StoreElement.Int16IntoCharArray_Valid() cil managed + { + // char[] a = new char[]; + // a[0] = 'a'; + + ldc.i4.1 + newarr [System.Runtime]System.Char + ldc.i4.0 + ldc.i4.s 97 + stelem.i2 + ret + } + + .method public hidebysig instance void LoadElement.UInt16FromCharArray_Valid() cil managed + { + .locals init ( + [0] char[], + [1] char + ) + + // char[] a = new char[]; + // a[0] = 'a'; + // char b = a[0]; + + ldc.i4.1 + newarr [System.Runtime]System.Char + stloc.0 + ldloc.0 + ldc.i4.0 + ldc.i4.s 97 + stelem.i2 + ldloc.0 + ldc.i4.0 + ldelem.u2 + stloc.1 + ret + } + + .method public hidebysig instance void LoadElement.UInt8FromBoolArray_Valid() cil managed + { + .locals init ( + [0] bool[], + [1] bool + ) + + // bool[] a = new bool[]; + // a[0] = true; + // bool b = a[0]; + + ldc.i4.1 + newarr [System.Runtime]System.Boolean + stloc.0 + ldloc.0 + ldc.i4.0 + ldc.i4.1 + stelem.i1 + ldloc.0 + ldc.i4.0 + ldelem.u1 + stloc.1 + ret + } +} diff --git a/src/ILVerify/tests/ILTests/LoadStoreIndirectTest.il b/src/ILVerify/tests/ILTests/LoadStoreIndirectTest.il index 41ae46731..3a9cc4cd5 100644 --- a/src/ILVerify/tests/ILTests/LoadStoreIndirectTest.il +++ b/src/ILVerify/tests/ILTests/LoadStoreIndirectTest.il @@ -126,4 +126,86 @@ stobj [System.Runtime]System.IO.Stream ret } + + .method static public hidebysig void LoadIndirect.AssignInt8ToBool_Valid(bool&) cil managed + { + .locals init (bool) + + // ref bool a; + // bool b; + // b = a; + + ldarg.0 + ldind.i1 + stloc.0 + ret + } + + .method static public hidebysig void LoadIndirect.AssignUInt8ToBool_Valid(bool&) cil managed + { + .locals init (bool) + + // ref bool a; + // bool b; + // b = a; + + ldarg.0 + ldind.u1 + stloc.0 + ret + } + + .method static public hidebysig void LoadIndirect.AssignInt16ToChar_Valid(char&) cil managed + { + .locals init (char) + + // ref char a; + // char b; + // b = a; + + ldarg.0 + ldind.i2 + stloc.0 + ret + } + + .method static public hidebysig void LoadIndirect.AssignUInt16ToChar_Valid(char&) cil managed + { + .locals init (char) + + // ref char a; + // char b; + // b = a; + + ldarg.0 + ldind.u2 + stloc.0 + ret + } + + .method static public hidebysig void StoreIndirect.AssignInt32ToCharRef_Valid(char&) cil managed + { + .locals init (char) + + // ref char a; + // a = 'a'; + + ldarg.0 + ldc.i4.s 97 + stind.i2 + ret + } + + .method static public hidebysig void StoreIndirect.AssignInt32ToBoolRef_Valid(bool&) cil managed + { + .locals init (bool) + + // ref bool a; + // a = true; + + ldarg.0 + ldc.i4.1 + stind.i1 + ret + } } |