From 128e05cd1172a5869cce8c64f898a5d1265db481 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 10 Dec 2017 19:03:26 +0100 Subject: [PATCH] Fix #937: support implicit Ref->I4 conversions These are not allowed in Ecma-335 Table 8: Conversion Operations, but the .NET runtime accepts them anyways, and C++/CLI generates them. --- ICSharpCode.Decompiler/IL/ILReader.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index 49a07eb2c..2eca213a3 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -1056,10 +1056,24 @@ namespace ICSharpCode.Decompiler.IL } else if (expectedType == StackType.I4 && inst.ResultType == StackType.I) { // C++/CLI also sometimes implicitly converts in the other direction: inst = new Conv(inst, PrimitiveType.I4, false, Sign.None); - } else if (expectedType == StackType.I && inst.ResultType == StackType.Ref) { + } else if (inst.ResultType == StackType.Ref) { // Implicitly stop GC tracking; this occurs when passing the result of 'ldloca' or 'ldsflda' // to a method expecting a native pointer. inst = new Conv(inst, PrimitiveType.I, false, Sign.None); + switch (expectedType) { + case StackType.I4: + inst = new Conv(inst, PrimitiveType.I4, false, Sign.None); + break; + case StackType.I: + break; + case StackType.I8: + inst = new Conv(inst, PrimitiveType.I8, false, Sign.None); + break; + default: + Warn($"Expected {expectedType}, but got {StackType.Ref}"); + inst = new Conv(inst, expectedType.ToKnownTypeCode().ToPrimitiveType(), false, Sign.None); + break; + } } else if (expectedType == StackType.Ref) { // implicitly start GC tracking / object to interior if (!inst.ResultType.IsIntegerType() && inst.ResultType != StackType.O) {