From abc3565b0572fe31b260e3535e1d164c1da23c47 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 30 May 2015 16:59:36 +0200 Subject: [PATCH] fix bugs in pointer decompilation --- .../CSharp/ExpressionBuilder.cs | 36 ++++++++++++++----- ICSharpCode.Decompiler/IL/ILReader.cs | 20 ++++++++--- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index af70d4d38..ecaa91543 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -349,19 +349,37 @@ namespace ICSharpCode.Decompiler.CSharp var resolverWithOverflowCheck = resolver.WithCheckForOverflow(inst.CheckForOverflow); var left = Translate(inst.Left); var right = Translate(inst.Right); - var rr = resolverWithOverflowCheck.ResolveBinaryOperator(op, left.ResolveResult, right.ResolveResult); - if (rr.IsError || rr.Type.GetStackType() != inst.ResultType - || !IsCompatibleWithSign(left.Type, inst.Sign) || !IsCompatibleWithSign(right.Type, inst.Sign)) - { - // Left and right operands are incompatible, so convert them to a common type - IType targetType = compilation.FindType(inst.ResultType.ToKnownTypeCode(inst.Sign)); + ResolveResult rr; + if (left.Type.IsKnownType(KnownTypeCode.IntPtr) || left.Type.IsKnownType(KnownTypeCode.UIntPtr) + || right.Type.IsKnownType(KnownTypeCode.IntPtr) || right.Type.IsKnownType(KnownTypeCode.UIntPtr)) { + IType targetType; + if (inst.Sign == Sign.Unsigned) { + targetType = compilation.FindType(KnownTypeCode.UInt64); + } else { + targetType = compilation.FindType(KnownTypeCode.Int64); + } left = left.ConvertTo(targetType, this); right = right.ConvertTo(targetType, this); + rr = new OperatorResolveResult(targetType, BinaryOperatorExpression.GetLinqNodeType(op, inst.CheckForOverflow), left.ResolveResult, right.ResolveResult); + var resultExpr = new BinaryOperatorExpression(left.Expression, op, right.Expression) + .WithILInstruction(inst) + .WithRR(rr); + return resultExpr.ConvertTo(compilation.FindType(inst.ResultType.ToKnownTypeCode()), this); + } else { rr = resolverWithOverflowCheck.ResolveBinaryOperator(op, left.ResolveResult, right.ResolveResult); + if (rr.IsError || rr.Type.GetStackType() != inst.ResultType + || !IsCompatibleWithSign(left.Type, inst.Sign) || !IsCompatibleWithSign(right.Type, inst.Sign)) + { + // Left and right operands are incompatible, so convert them to a common type + IType targetType = compilation.FindType(inst.ResultType.ToKnownTypeCode(inst.Sign)); + left = left.ConvertTo(targetType, this); + right = right.ConvertTo(targetType, this); + rr = resolverWithOverflowCheck.ResolveBinaryOperator(op, left.ResolveResult, right.ResolveResult); + } + return new BinaryOperatorExpression(left.Expression, op, right.Expression) + .WithILInstruction(inst) + .WithRR(rr); } - return new BinaryOperatorExpression(left.Expression, op, right.Expression) - .WithILInstruction(inst) - .WithRR(rr); } /// diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index edcadc30e..19ba9683c 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -878,10 +878,22 @@ namespace ICSharpCode.Decompiler.IL int target = shortForm ? reader.ReadSByte() : reader.ReadInt32(); target += reader.Position; ILInstruction condition = Pop(); - if (condition.ResultType == StackType.O) { - // introduce explicit comparison with null - condition = new Ceq(condition, new LdNull()); - negate = !negate; + switch (condition.ResultType) { + case StackType.O: + // introduce explicit comparison with null + condition = new Ceq(condition, new LdNull()); + negate = !negate; + break; + case StackType.I: + // introduce explicit comparison with 0 + condition = new Ceq(condition, new LdcI4(0)); + negate = !negate; + break; + case StackType.I8: + // introduce explicit comparison with 0 + condition = new Ceq(condition, new LdcI8(0)); + negate = !negate; + break; } if (negate) { condition = new LogicNot(condition);