From a80672ba420ef429f1244ec0ab6d614c337a476d Mon Sep 17 00:00:00 2001 From: Eugene Date: Thu, 6 Sep 2018 02:48:28 +0300 Subject: [PATCH] Change rules for VisitUnboxAny & fix issue https://github.com/icsharpcode/ILSpy/issues/1256 --- .../ICSharpCode.Decompiler.Tests.csproj | 2 + .../ILPrettyTestRunner.cs | 6 ++ .../TestCases/ILPretty/Issue1256.cs | 17 ++++++ .../TestCases/ILPretty/Issue1256.il | 58 +++++++++++++++++++ .../CSharp/ExpressionBuilder.cs | 9 +-- 5 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1256.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1256.il diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index ed47fa69c..229eea694 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -70,9 +70,11 @@ + + diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs index 1f2f12598..12fcbb8fd 100644 --- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs @@ -118,6 +118,12 @@ namespace ICSharpCode.Decompiler.Tests Run(); } + [Test] + public void Issue1256() + { + Run(); + } + [Test] public void FSharpLoops_Debug() { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1256.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1256.cs new file mode 100644 index 000000000..9f35382ff --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1256.cs @@ -0,0 +1,17 @@ +using System; + +namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty +{ + internal class Issue1256 + { + public void Method(Enum e, object o, string s) + { + int num = (int)(object)e; + object obj = new object(); + int num2 = (int)obj; + long num3 = (long)o; + int num4 = (int)(object)s; + int num5 = (int)num3; + } + } +} \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1256.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1256.il new file mode 100644 index 000000000..12fe8844b --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1256.il @@ -0,0 +1,58 @@ +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1256 + extends [mscorlib]System.Object +{ + // Methods + .method public hidebysig + instance void Method ( + class [mscorlib]System.Enum e, + object o, + string s + ) cil managed + { + // Method begins at RVA 0x2050 + // Code size 41 (0x29) + .maxstack 1 + .locals init ( + [0] int32, + [1] object, + [2] int32, + [3] int64, + [4] int32, + [5] int32 + ) + + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: unbox.any [mscorlib]System.Int32 + IL_0007: stloc.0 + IL_0008: newobj instance void [mscorlib]System.Object::.ctor() + IL_000d: stloc.1 + IL_000e: ldloc.1 + IL_000f: unbox.any [mscorlib]System.Int32 + IL_0014: stloc.2 + IL_0015: ldarg.2 + IL_0016: unbox.any [mscorlib]System.Int64 + IL_001b: stloc.3 + IL_001c: ldarg.3 + IL_001d: unbox.any [mscorlib]System.Int32 + IL_0022: stloc.s 4 + IL_0024: ldloc.3 + IL_0025: conv.i4 + IL_0026: stloc.s 5 + IL_0028: ret + } // end of method Issue1256::Method + + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x2085 + // Code size 8 (0x8) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method Issue1256::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1256 diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index bd2551125..b44179140 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1877,10 +1877,6 @@ namespace ICSharpCode.Decompiler.CSharp // isinst followed by unbox.any of the same type is used for as-casts to generic types return arg.WithILInstruction(inst); } - if (arg.Type.IsReferenceType != true) { - // ensure we treat the input as a reference type - arg = arg.ConvertTo(compilation.FindType(KnownTypeCode.Object), this); - } IType targetType = inst.Type; if (targetType.Kind == TypeKind.TypeParameter) { @@ -1892,6 +1888,11 @@ namespace ICSharpCode.Decompiler.CSharp arg = arg.ConvertTo(((ITypeParameter)targetType).EffectiveBaseClass, this); } } + else { + // Before unboxing arg must be a object + arg = arg.ConvertTo(compilation.FindType(KnownTypeCode.Object), this); + } + return new CastExpression(ConvertType(targetType), arg.Expression) .WithILInstruction(inst) .WithRR(new ConversionResolveResult(targetType, arg.ResolveResult, Conversion.UnboxingConversion));