From bbe16584f769ac7894c8362ee5afee84506ee255 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 6 Jun 2018 22:48:36 +0200 Subject: [PATCH] Fix #1150: - Allow unknown type in BinaryNumericInstruction - Make conversions explicit: I+I8=I8, I4+I8=I8, F4+F8=F8 --- ICSharpCode.Decompiler/IL/ILReader.cs | 24 ++++++++++++++----- .../Instructions/BinaryNumericInstruction.cs | 1 - 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index 8ab357092..f15768ac5 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -1083,10 +1083,11 @@ namespace ICSharpCode.Decompiler.IL ILInstruction inst = Pop(); switch (inst.ResultType) { case StackType.I4: + case StackType.I8: + case StackType.Unknown: return new Conv(inst, PrimitiveType.I, false, Sign.None); case StackType.I: case StackType.Ref: - case StackType.Unknown: return inst; default: Warn("Expected native int or pointer, but got " + inst.ResultType); @@ -1484,13 +1485,24 @@ namespace ICSharpCode.Decompiler.IL var left = Pop(); if (@operator != BinaryNumericOperator.ShiftLeft && @operator != BinaryNumericOperator.ShiftRight) { // make the implicit I4->I conversion explicit: - if (left.ResultType == StackType.I4 && right.ResultType == StackType.I) { - left = new Conv(left, PrimitiveType.I, false, Sign.None); - } else if (left.ResultType == StackType.I && right.ResultType == StackType.I4) { - right = new Conv(right, PrimitiveType.I, false, Sign.None); - } + MakeExplicitConversion(sourceType: StackType.I4, targetType: StackType.I, conversionType: PrimitiveType.I); + // I4->I8 conversion: + MakeExplicitConversion(sourceType: StackType.I4, targetType: StackType.I8, conversionType: PrimitiveType.I8); + // I->I8 conversion: + MakeExplicitConversion(sourceType: StackType.I, targetType: StackType.I8, conversionType: PrimitiveType.I8); + // F4->F8 conversion: + MakeExplicitConversion(sourceType: StackType.F4, targetType: StackType.F8, conversionType: PrimitiveType.R8); } return Push(new BinaryNumericInstruction(@operator, left, right, checkForOverflow, sign)); + + void MakeExplicitConversion(StackType sourceType, StackType targetType, PrimitiveType conversionType) + { + if (left.ResultType == sourceType && right.ResultType == targetType) { + left = new Conv(left, conversionType, false, Sign.None); + } else if (left.ResultType == targetType && right.ResultType == sourceType) { + right = new Conv(right, conversionType, false, Sign.None); + } + } } ILInstruction DecodeJmp() diff --git a/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs index 7ea3d754e..8df06d54e 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs @@ -91,7 +91,6 @@ namespace ICSharpCode.Decompiler.IL this.RightInputType = rightInputType; this.IsLifted = isLifted; this.resultType = ComputeResultType(op, LeftInputType, RightInputType); - Debug.Assert(resultType != StackType.Unknown); } internal static StackType ComputeResultType(BinaryNumericOperator op, StackType left, StackType right)