From ad5ba9295e934c32f607cbcc726499d830208ff3 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 14 Feb 2020 23:43:55 +0100 Subject: [PATCH] Fix #1924: preserve hexadecimal format when converting literal to wider type --- .../ICSharpCode.Decompiler.Tests.csproj | 2 + .../ILPrettyTestRunner.cs | 6 ++ .../TestCases/ILPretty/Issue1922.cs | 15 +++++ .../TestCases/ILPretty/Issue1922.il | 59 +++++++++++++++++++ .../CSharp/TranslatedExpression.cs | 6 +- 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.il diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index d382a1af3..1f9c4232c 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -60,6 +60,7 @@ + @@ -81,6 +82,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs index 916084055..65cbac376 100644 --- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs @@ -94,6 +94,12 @@ namespace ICSharpCode.Decompiler.Tests Run(); } + [Test] + public void Issue1922() + { + Run(); + } + [Test] public void FSharpUsing_Debug() { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.cs new file mode 100644 index 000000000..d29dca4e5 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.cs @@ -0,0 +1,15 @@ +namespace Issue1922 +{ + public class Program + { + public static long fnWorks(int x, int y) + { + return (((long)y & 0xFFFFFFL) << 24) | ((long)x & 0xFFFFFFL); + } + + public static long fnFails(int x, int y) + { + return ((y & 0xFFFFFFL) << 24) | (x & 0xFFFFFFL); + } + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.il new file mode 100644 index 000000000..2d507e885 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.il @@ -0,0 +1,59 @@ +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) + .ver 4:0:0:0 +} +.assembly Issue1922 +{ + .hash algorithm 0x00008004 + .ver 1:0:4059:39717 +} +.module Issue1389.dll +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000003 // ILONLY 32BITREQUIRED + +.class public auto ansi beforefieldinit Issue1922.Program + extends [mscorlib]System.Object +{ + // Methods + .method public hidebysig static int64 fnWorks (int32 x, int32 y) cil managed + { + .maxstack 8 + + ldarg.1 + conv.i8 + ldc.i4 16777215 + conv.i8 + and + ldc.i4.s 24 + shl + ldarg.0 + conv.i8 + ldc.i4 16777215 + conv.i8 + and + or + ret + } + + .method public hidebysig static int64 fnFails (int32 x, int32 y) cil managed + { + .maxstack 8 + + ldarg.1 + conv.i8 + ldc.i8 16777215 + and + ldc.i4.s 24 + shl + ldarg.0 + conv.i8 + ldc.i8 16777215 + and + or + ret + } +} // end of class Issue1922.Program \ No newline at end of file diff --git a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs index d16146236..bbdceed64 100644 --- a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs +++ b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs @@ -431,8 +431,12 @@ namespace ICSharpCode.Decompiler.CSharp } var rr = expressionBuilder.resolver.WithCheckForOverflow(checkForOverflow).ResolveCast(targetType, ResolveResult); if (rr.IsCompileTimeConstant && !rr.IsError) { - return expressionBuilder.ConvertConstantValue(rr, allowImplicitConversion) + var convertedResult = expressionBuilder.ConvertConstantValue(rr, allowImplicitConversion) .WithILInstruction(this.ILInstructions); + if (convertedResult.Expression is PrimitiveExpression outputLiteral && this.Expression is PrimitiveExpression inputLiteral) { + outputLiteral.Format = inputLiteral.Format; + } + return convertedResult; } else if (rr.IsError && targetType.IsReferenceType == true && type.IsReferenceType == true) { // Conversion between two reference types, but no direct cast allowed? cast via object // Just make sure we avoid infinite recursion even if the resolver falsely claims we can't cast directly: