diff options
author | Samuel Arzt <arzt.samuel@live.de> | 2017-12-13 01:52:10 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-12-13 01:52:10 +0300 |
commit | 36d1ccfb9f7dad06c7ecba13815e3b35cd6557f7 (patch) | |
tree | b4fa5b996a7fff911b1f486f0a4c153f446c526b /src/ILVerify | |
parent | 14915c5fe5cbaa24c0aa72d0b84089c8c834b1e0 (diff) |
[ILVerify] Fix leave from catch into enclosing try and assignability of readonly ByRefs (#5097)
* Fixed leave target validation using target try index instead of src handler index.
* Fixed IsAssignable not checking readonlyness of byrefs.
* Renamed CatchIntoTry test to be more fitting.
Diffstat (limited to 'src/ILVerify')
-rw-r--r-- | src/ILVerify/src/ILImporter.StackValue.cs | 6 | ||||
-rw-r--r-- | src/ILVerify/src/ILImporter.Verify.cs | 2 | ||||
-rw-r--r-- | src/ILVerify/tests/ILTests/CallTests.il | 17 | ||||
-rw-r--r-- | src/ILVerify/tests/ILTests/ExceptionRegionTests.il | 58 |
4 files changed, 54 insertions, 29 deletions
diff --git a/src/ILVerify/src/ILImporter.StackValue.cs b/src/ILVerify/src/ILImporter.StackValue.cs index 30f4c7f32..ad2497b1c 100644 --- a/src/ILVerify/src/ILImporter.StackValue.cs +++ b/src/ILVerify/src/ILImporter.StackValue.cs @@ -228,7 +228,7 @@ namespace Internal.IL case StackValueKind.Float: return "Double"; case StackValueKind.ByRef: - return "address of " + TypeToStringForByRef(Type); + return (IsReadOnly ? "readonly " : "") + "address of " + TypeToStringForByRef(Type); case StackValueKind.ObjRef: return (Type != null) ? "ref '" + Type.ToString() + "'" : "Nullobjref 'NullReference'"; case StackValueKind.ValueType: @@ -488,7 +488,7 @@ namespace Internal.IL bool IsAssignable(StackValue src, StackValue dst) { - if (src.Kind == dst.Kind && src.Type == dst.Type) + if (src.Kind == dst.Kind && src.Type == dst.Type && src.IsReadOnly == dst.IsReadOnly) return true; if (dst.Type == null) @@ -513,6 +513,8 @@ namespace Internal.IL return false; case StackValueKind.ByRef: + if (dst.Kind == StackValueKind.ByRef && dst.IsReadOnly) + return src.Type == dst.Type; // TODO: Other cases - variance, etc. diff --git a/src/ILVerify/src/ILImporter.Verify.cs b/src/ILVerify/src/ILImporter.Verify.cs index 664a32cad..c7d156d16 100644 --- a/src/ILVerify/src/ILImporter.Verify.cs +++ b/src/ILVerify/src/ILImporter.Verify.cs @@ -614,7 +614,7 @@ again: { if (target.TryIndex.HasValue) { - ref var srcRegion = ref _exceptionRegions[target.TryIndex.Value].ILRegion; + ref var srcRegion = ref _exceptionRegions[src.HandlerIndex.Value].ILRegion; ref var targetRegion = ref _exceptionRegions[target.TryIndex.Value].ILRegion; // If target is not associated try block, and not enclosing srcRegion diff --git a/src/ILVerify/tests/ILTests/CallTests.il b/src/ILVerify/tests/ILTests/CallTests.il index e39ce22ff..a0637a25c 100644 --- a/src/ILVerify/tests/ILTests/CallTests.il +++ b/src/ILVerify/tests/ILTests/CallTests.il @@ -24,6 +24,11 @@ { ret } + + .method public hidebysig static void InObjectMethod([in] object&) cil managed + { + ret + } } .class public auto ansi beforefieldinit DerivedClass @@ -130,4 +135,16 @@ call instance void SimpleClass::VirtualMethod() ret } + + .method public hidebysig instance void Call.ReadonlyByRefForInArg_Invalid_StackUnexpected(object[] objectArray) cil managed + { + // SimpleClass.InObjectMethod(objectArray[0]); + + ldarg.1 + ldc.i4.0 + readonly. + ldelema [System.Runtime]System.Object + call void SimpleClass::InObjectMethod(object&) + ret + } } diff --git a/src/ILVerify/tests/ILTests/ExceptionRegionTests.il b/src/ILVerify/tests/ILTests/ExceptionRegionTests.il index 8b388044d..6c390f6b7 100644 --- a/src/ILVerify/tests/ILTests/ExceptionRegionTests.il +++ b/src/ILVerify/tests/ILTests/ExceptionRegionTests.il @@ -453,30 +453,6 @@ ret } - .method public instance void Leave.IntoEnclosingTry_Valid() cil managed - { - .try - { - .try - { - leave EnclosingTry - } - catch [System.Runtime]System.Object - { - leave EnclosingTry - } - EnclosingTry: - leave MethodEnd - } - finally - { - endfinally - } - - MethodEnd: - ret - } - .method public instance void Leave.OutOfCatch_Valid() cil managed { .try @@ -572,7 +548,7 @@ ret } - .method public instance void Leave.CatchToEnclosingTry_Valid() cil managed + .method public instance void Leave.TryToEnclosingCatch_Valid() cil managed { .try { @@ -582,16 +558,46 @@ { .try { - leave EnclosingTry + leave EnclosingCatch } finally { endfinally } + EnclosingCatch: + leave MethodEnd + } + + MethodEnd: + ret + } + + .method public instance void Leave.CatchToEnclosingTry_Valid() cil managed + { + .try + { + .try + { + leave MethodEnd + } + catch [System.Runtime]System.Object + { + leave EnclosingTry + } + EnclosingTry: leave MethodEnd } + filter + { + pop + ldc.i4.0 + endfilter + } + { + leave MethodEnd + } MethodEnd: ret |