diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
index 706033307..d2a513d71 100644
--- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
+++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
@@ -73,6 +73,7 @@
+
diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
index 445e23082..3636325ec 100644
--- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
+++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
@@ -329,6 +329,12 @@ namespace ICSharpCode.Decompiler.Tests
RunForLibrary(cscOptions: cscOptions);
}
+ [Test]
+ public void ConstantsTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
+ {
+ RunForLibrary(cscOptions: cscOptions);
+ }
+
[Test]
public void Issue1080([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions)
{
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.cs
new file mode 100644
index 000000000..83a151048
--- /dev/null
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.cs
@@ -0,0 +1,31 @@
+namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
+{
+ internal class ConstantsTests
+ {
+ public ulong Issue1308(ulong u = 8uL)
+ {
+ Test((u & uint.MaxValue) != 0);
+ return 18446744069414584320uL;
+ }
+
+ public void Byte_BitmaskingInCondition(byte v)
+ {
+ Test((v & 0xF) == 0);
+ Test((v & 0x123) == 0);
+ Test((v | 0xF) == 0);
+ Test((v | 0x123) == 0);
+ }
+
+ public void SByte_BitmaskingInCondition(sbyte v)
+ {
+ Test((v & 0xF) == 0);
+ Test((v & 0x123) == 0);
+ Test((v | 0xF) == 0);
+ Test((v | 0x123) == 0);
+ }
+
+ private void Test(bool expr)
+ {
+ }
+ }
+}
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.il
new file mode 100644
index 000000000..ef941f9e7
--- /dev/null
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.il
@@ -0,0 +1,169 @@
+
+
+
+
+// Metadata version: v4.0.30319
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 4:0:0:0
+}
+.assembly ConstantsTests
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
+ 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
+ .permissionset reqmin
+ = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module ConstantsTests.dll
+.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
+.imagebase 0x10000000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig instance uint64
+ Issue1308([opt] uint64 u) cil managed
+ {
+ .param [1] = uint64(0x8)
+ // Code size 33 (0x21)
+ .maxstack 3
+ .locals init (uint64 V_0)
+ IL_0000: nop
+ IL_0001: ldarg.0
+ IL_0002: ldarg.1
+ IL_0003: ldc.i4.m1
+ IL_0004: conv.u8
+ IL_0005: and
+ IL_0006: ldc.i4.0
+ IL_0007: conv.i8
+ IL_0008: ceq
+ IL_000a: ldc.i4.0
+ IL_000b: ceq
+ IL_000d: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_0012: nop
+ IL_0013: ldc.i8 0xffffffff00000000
+ IL_001c: stloc.0
+ IL_001d: br.s IL_001f
+
+ IL_001f: ldloc.0
+ IL_0020: ret
+ } // end of method ConstantsTests::Issue1308
+
+ .method public hidebysig instance void
+ Byte_BitmaskingInCondition(uint8 v) cil managed
+ {
+ // Code size 64 (0x40)
+ .maxstack 3
+ IL_0000: nop
+ IL_0001: ldarg.0
+ IL_0002: ldarg.1
+ IL_0003: ldc.i4.s 15
+ IL_0005: and
+ IL_0006: ldc.i4.0
+ IL_0007: ceq
+ IL_0009: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_000e: nop
+ IL_000f: ldarg.0
+ IL_0010: ldarg.1
+ IL_0011: ldc.i4 0x123
+ IL_0016: and
+ IL_0017: ldc.i4.0
+ IL_0018: ceq
+ IL_001a: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_001f: nop
+ IL_0020: ldarg.0
+ IL_0021: ldarg.1
+ IL_0022: ldc.i4.s 15
+ IL_0024: or
+ IL_0025: ldc.i4.0
+ IL_0026: ceq
+ IL_0028: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_002d: nop
+ IL_002e: ldarg.0
+ IL_002f: ldarg.1
+ IL_0030: ldc.i4 0x123
+ IL_0035: or
+ IL_0036: ldc.i4.0
+ IL_0037: ceq
+ IL_0039: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_003e: nop
+ IL_003f: ret
+ } // end of method ConstantsTests::Byte_BitmaskingInCondition
+
+ .method public hidebysig instance void
+ SByte_BitmaskingInCondition(int8 v) cil managed
+ {
+ // Code size 64 (0x40)
+ .maxstack 3
+ IL_0000: nop
+ IL_0001: ldarg.0
+ IL_0002: ldarg.1
+ IL_0003: ldc.i4.s 15
+ IL_0005: and
+ IL_0006: ldc.i4.0
+ IL_0007: ceq
+ IL_0009: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_000e: nop
+ IL_000f: ldarg.0
+ IL_0010: ldarg.1
+ IL_0011: ldc.i4 0x123
+ IL_0016: and
+ IL_0017: ldc.i4.0
+ IL_0018: ceq
+ IL_001a: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_001f: nop
+ IL_0020: ldarg.0
+ IL_0021: ldarg.1
+ IL_0022: ldc.i4.s 15
+ IL_0024: or
+ IL_0025: ldc.i4.0
+ IL_0026: ceq
+ IL_0028: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_002d: nop
+ IL_002e: ldarg.0
+ IL_002f: ldarg.1
+ IL_0030: ldc.i4 0x123
+ IL_0035: or
+ IL_0036: ldc.i4.0
+ IL_0037: ceq
+ IL_0039: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_003e: nop
+ IL_003f: ret
+ } // end of method ConstantsTests::SByte_BitmaskingInCondition
+
+ .method private hidebysig instance void
+ Test(bool expr) cil managed
+ {
+ // Code size 2 (0x2)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ret
+ } // end of method ConstantsTests::Test
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method ConstantsTests::.ctor
+
+} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.opt.il
new file mode 100644
index 000000000..8ada5c036
--- /dev/null
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.opt.il
@@ -0,0 +1,151 @@
+
+
+
+
+// Metadata version: v4.0.30319
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 4:0:0:0
+}
+.assembly ConstantsTests.opt
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
+ 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
+ .permissionset reqmin
+ = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module ConstantsTests.opt.dll
+.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
+.imagebase 0x10000000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig instance uint64
+ Issue1308([opt] uint64 u) cil managed
+ {
+ .param [1] = uint64(0x8)
+ // Code size 27 (0x1b)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: ldc.i4.m1
+ IL_0003: conv.u8
+ IL_0004: and
+ IL_0005: ldc.i4.0
+ IL_0006: conv.i8
+ IL_0007: ceq
+ IL_0009: ldc.i4.0
+ IL_000a: ceq
+ IL_000c: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_0011: ldc.i8 0xffffffff00000000
+ IL_001a: ret
+ } // end of method ConstantsTests::Issue1308
+
+ .method public hidebysig instance void
+ Byte_BitmaskingInCondition(uint8 v) cil managed
+ {
+ // Code size 59 (0x3b)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: ldc.i4.s 15
+ IL_0004: and
+ IL_0005: ldc.i4.0
+ IL_0006: ceq
+ IL_0008: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_000d: ldarg.0
+ IL_000e: ldarg.1
+ IL_000f: ldc.i4 0x123
+ IL_0014: and
+ IL_0015: ldc.i4.0
+ IL_0016: ceq
+ IL_0018: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_001d: ldarg.0
+ IL_001e: ldarg.1
+ IL_001f: ldc.i4.s 15
+ IL_0021: or
+ IL_0022: ldc.i4.0
+ IL_0023: ceq
+ IL_0025: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_002a: ldarg.0
+ IL_002b: ldarg.1
+ IL_002c: ldc.i4 0x123
+ IL_0031: or
+ IL_0032: ldc.i4.0
+ IL_0033: ceq
+ IL_0035: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_003a: ret
+ } // end of method ConstantsTests::Byte_BitmaskingInCondition
+
+ .method public hidebysig instance void
+ SByte_BitmaskingInCondition(int8 v) cil managed
+ {
+ // Code size 59 (0x3b)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: ldc.i4.s 15
+ IL_0004: and
+ IL_0005: ldc.i4.0
+ IL_0006: ceq
+ IL_0008: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_000d: ldarg.0
+ IL_000e: ldarg.1
+ IL_000f: ldc.i4 0x123
+ IL_0014: and
+ IL_0015: ldc.i4.0
+ IL_0016: ceq
+ IL_0018: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_001d: ldarg.0
+ IL_001e: ldarg.1
+ IL_001f: ldc.i4.s 15
+ IL_0021: or
+ IL_0022: ldc.i4.0
+ IL_0023: ceq
+ IL_0025: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_002a: ldarg.0
+ IL_002b: ldarg.1
+ IL_002c: ldc.i4 0x123
+ IL_0031: or
+ IL_0032: ldc.i4.0
+ IL_0033: ceq
+ IL_0035: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_003a: ret
+ } // end of method ConstantsTests::SByte_BitmaskingInCondition
+
+ .method private hidebysig instance void
+ Test(bool expr) cil managed
+ {
+ // Code size 1 (0x1)
+ .maxstack 8
+ IL_0000: ret
+ } // end of method ConstantsTests::Test
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method ConstantsTests::.ctor
+
+} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.opt.roslyn.il
new file mode 100644
index 000000000..db8a15f20
--- /dev/null
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.opt.roslyn.il
@@ -0,0 +1,153 @@
+
+
+
+
+// Metadata version: v4.0.30319
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 4:0:0:0
+}
+.assembly ConstantsTests
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
+ 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
+
+ // --- The following custom attribute is added automatically, do not uncomment -------
+ // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 )
+
+ .permissionset reqmin
+ = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module ConstantsTests.dll
+.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
+.imagebase 0x10000000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig instance uint64
+ Issue1308([opt] uint64 u) cil managed
+ {
+ .param [1] = uint64(0x8)
+ // Code size 24 (0x18)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: ldc.i4.m1
+ IL_0003: conv.u8
+ IL_0004: and
+ IL_0005: ldc.i4.0
+ IL_0006: conv.i8
+ IL_0007: cgt.un
+ IL_0009: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_000e: ldc.i8 0xffffffff00000000
+ IL_0017: ret
+ } // end of method ConstantsTests::Issue1308
+
+ .method public hidebysig instance void
+ Byte_BitmaskingInCondition(uint8 v) cil managed
+ {
+ // Code size 59 (0x3b)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: ldc.i4.s 15
+ IL_0004: and
+ IL_0005: ldc.i4.0
+ IL_0006: ceq
+ IL_0008: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_000d: ldarg.0
+ IL_000e: ldarg.1
+ IL_000f: ldc.i4 0x123
+ IL_0014: and
+ IL_0015: ldc.i4.0
+ IL_0016: ceq
+ IL_0018: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_001d: ldarg.0
+ IL_001e: ldarg.1
+ IL_001f: ldc.i4.s 15
+ IL_0021: or
+ IL_0022: ldc.i4.0
+ IL_0023: ceq
+ IL_0025: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_002a: ldarg.0
+ IL_002b: ldarg.1
+ IL_002c: ldc.i4 0x123
+ IL_0031: or
+ IL_0032: ldc.i4.0
+ IL_0033: ceq
+ IL_0035: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_003a: ret
+ } // end of method ConstantsTests::Byte_BitmaskingInCondition
+
+ .method public hidebysig instance void
+ SByte_BitmaskingInCondition(int8 v) cil managed
+ {
+ // Code size 59 (0x3b)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: ldc.i4.s 15
+ IL_0004: and
+ IL_0005: ldc.i4.0
+ IL_0006: ceq
+ IL_0008: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_000d: ldarg.0
+ IL_000e: ldarg.1
+ IL_000f: ldc.i4 0x123
+ IL_0014: and
+ IL_0015: ldc.i4.0
+ IL_0016: ceq
+ IL_0018: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_001d: ldarg.0
+ IL_001e: ldarg.1
+ IL_001f: ldc.i4.s 15
+ IL_0021: or
+ IL_0022: ldc.i4.0
+ IL_0023: ceq
+ IL_0025: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_002a: ldarg.0
+ IL_002b: ldarg.1
+ IL_002c: ldc.i4 0x123
+ IL_0031: or
+ IL_0032: ldc.i4.0
+ IL_0033: ceq
+ IL_0035: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_003a: ret
+ } // end of method ConstantsTests::SByte_BitmaskingInCondition
+
+ .method private hidebysig instance void
+ Test(bool expr) cil managed
+ {
+ // Code size 1 (0x1)
+ .maxstack 8
+ IL_0000: ret
+ } // end of method ConstantsTests::Test
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method ConstantsTests::.ctor
+
+} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.roslyn.il
new file mode 100644
index 000000000..c81eac37c
--- /dev/null
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.roslyn.il
@@ -0,0 +1,172 @@
+
+
+
+
+// Metadata version: v4.0.30319
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 4:0:0:0
+}
+.assembly ConstantsTests
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
+ 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
+
+ // --- The following custom attribute is added automatically, do not uncomment -------
+ // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )
+
+ .permissionset reqmin
+ = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module ConstantsTests.dll
+.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
+.imagebase 0x10000000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig instance uint64
+ Issue1308([opt] uint64 u) cil managed
+ {
+ .param [1] = uint64(0x8)
+ // Code size 30 (0x1e)
+ .maxstack 3
+ .locals init (uint64 V_0)
+ IL_0000: nop
+ IL_0001: ldarg.0
+ IL_0002: ldarg.1
+ IL_0003: ldc.i4.m1
+ IL_0004: conv.u8
+ IL_0005: and
+ IL_0006: ldc.i4.0
+ IL_0007: conv.i8
+ IL_0008: cgt.un
+ IL_000a: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_000f: nop
+ IL_0010: ldc.i8 0xffffffff00000000
+ IL_0019: stloc.0
+ IL_001a: br.s IL_001c
+
+ IL_001c: ldloc.0
+ IL_001d: ret
+ } // end of method ConstantsTests::Issue1308
+
+ .method public hidebysig instance void
+ Byte_BitmaskingInCondition(uint8 v) cil managed
+ {
+ // Code size 64 (0x40)
+ .maxstack 3
+ IL_0000: nop
+ IL_0001: ldarg.0
+ IL_0002: ldarg.1
+ IL_0003: ldc.i4.s 15
+ IL_0005: and
+ IL_0006: ldc.i4.0
+ IL_0007: ceq
+ IL_0009: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_000e: nop
+ IL_000f: ldarg.0
+ IL_0010: ldarg.1
+ IL_0011: ldc.i4 0x123
+ IL_0016: and
+ IL_0017: ldc.i4.0
+ IL_0018: ceq
+ IL_001a: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_001f: nop
+ IL_0020: ldarg.0
+ IL_0021: ldarg.1
+ IL_0022: ldc.i4.s 15
+ IL_0024: or
+ IL_0025: ldc.i4.0
+ IL_0026: ceq
+ IL_0028: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_002d: nop
+ IL_002e: ldarg.0
+ IL_002f: ldarg.1
+ IL_0030: ldc.i4 0x123
+ IL_0035: or
+ IL_0036: ldc.i4.0
+ IL_0037: ceq
+ IL_0039: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_003e: nop
+ IL_003f: ret
+ } // end of method ConstantsTests::Byte_BitmaskingInCondition
+
+ .method public hidebysig instance void
+ SByte_BitmaskingInCondition(int8 v) cil managed
+ {
+ // Code size 64 (0x40)
+ .maxstack 3
+ IL_0000: nop
+ IL_0001: ldarg.0
+ IL_0002: ldarg.1
+ IL_0003: ldc.i4.s 15
+ IL_0005: and
+ IL_0006: ldc.i4.0
+ IL_0007: ceq
+ IL_0009: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_000e: nop
+ IL_000f: ldarg.0
+ IL_0010: ldarg.1
+ IL_0011: ldc.i4 0x123
+ IL_0016: and
+ IL_0017: ldc.i4.0
+ IL_0018: ceq
+ IL_001a: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_001f: nop
+ IL_0020: ldarg.0
+ IL_0021: ldarg.1
+ IL_0022: ldc.i4.s 15
+ IL_0024: or
+ IL_0025: ldc.i4.0
+ IL_0026: ceq
+ IL_0028: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_002d: nop
+ IL_002e: ldarg.0
+ IL_002f: ldarg.1
+ IL_0030: ldc.i4 0x123
+ IL_0035: or
+ IL_0036: ldc.i4.0
+ IL_0037: ceq
+ IL_0039: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests::Test(bool)
+ IL_003e: nop
+ IL_003f: ret
+ } // end of method ConstantsTests::SByte_BitmaskingInCondition
+
+ .method private hidebysig instance void
+ Test(bool expr) cil managed
+ {
+ // Code size 2 (0x2)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ret
+ } // end of method ConstantsTests::Test
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // 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 ConstantsTests::.ctor
+
+} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstantsTests
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs
index 435bdc06a..1631e8bba 100644
--- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs
@@ -591,7 +591,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
num++;
}
- return -2147483648;
+ return int.MinValue;
}
//public int InterestingLoop()
@@ -615,7 +615,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
// num++;
// }
// // This instruction is still dominated by the loop header
- // num = -2147483648;//int.MinValue;
+ // num = int.MinValue;
// }
// return num;
//}
@@ -638,7 +638,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
num++;
}
}
- num = -2147483648;
+ num = int.MinValue;
}
return num;
}
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.cs
index 16fadeecf..80631f96a 100644
--- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.cs
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.cs
@@ -45,6 +45,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Decimal();
Decimal(5m);
+
+#if CS72
+ NamedArgument(flag: true);
+ NamedArgument(flag: false);
+#endif
}
private void Conflicts()
@@ -147,6 +152,10 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
}
+ private void NamedArgument(bool flag)
+ {
+ }
+
private string Get(out int a)
{
throw null;
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.il
index cc01fe3db..79df342db 100644
--- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.il
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.il
@@ -474,6 +474,15 @@
IL_0001: ret
} // end of method OptionalArguments::OnlyDifferenceIsLastArgumentCastNecessary
+ .method private hidebysig instance void
+ NamedArgument(bool flag) cil managed
+ {
+ // Code size 2 (0x2)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ret
+ } // end of method OptionalArguments::NamedArgument
+
.method private hidebysig instance string
Get([out] int32& a) cil managed
{
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.opt.il
index e34d0deb9..f4c232fe7 100644
--- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.opt.il
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.opt.il
@@ -425,6 +425,14 @@
IL_0000: ret
} // end of method OptionalArguments::OnlyDifferenceIsLastArgumentCastNecessary
+ .method private hidebysig instance void
+ NamedArgument(bool flag) cil managed
+ {
+ // Code size 1 (0x1)
+ .maxstack 8
+ IL_0000: ret
+ } // end of method OptionalArguments::NamedArgument
+
.method private hidebysig instance string
Get([out] int32& a) cil managed
{
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.opt.roslyn.il
index 179bc8bff..58c97a131 100644
--- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.opt.roslyn.il
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.opt.roslyn.il
@@ -73,7 +73,7 @@
.method private hidebysig instance void
SimpleTests() cil managed
{
- // Code size 64 (0x40)
+ // Code size 78 (0x4e)
.maxstack 3
IL_0000: ldarg.0
IL_0001: ldc.i4.s 10
@@ -98,7 +98,13 @@
IL_0034: ldc.i4.5
IL_0035: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_003a: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.OptionalArguments::Decimal(valuetype [mscorlib]System.Decimal)
- IL_003f: ret
+ IL_003f: ldarg.0
+ IL_0040: ldc.i4.1
+ IL_0041: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.OptionalArguments::NamedArgument(bool)
+ IL_0046: ldarg.0
+ IL_0047: ldc.i4.0
+ IL_0048: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.OptionalArguments::NamedArgument(bool)
+ IL_004d: ret
} // end of method OptionalArguments::SimpleTests
.method private hidebysig instance void
@@ -401,6 +407,14 @@
IL_0000: ret
} // end of method OptionalArguments::OnlyDifferenceIsLastArgumentCastNecessary
+ .method private hidebysig instance void
+ NamedArgument(bool flag) cil managed
+ {
+ // Code size 1 (0x1)
+ .maxstack 8
+ IL_0000: ret
+ } // end of method OptionalArguments::NamedArgument
+
.method private hidebysig instance string
Get([out] int32& a) cil managed
{
@@ -423,15 +437,16 @@
.size 12
} // end of class '__StaticArrayInitTypeSize=12'
- .field static assembly initonly valuetype ''/'__StaticArrayInitTypeSize=12' '0F3DD643C5167ACFC541F72809FFF828A6E41494' at I_00002DC4
- .field static assembly initonly valuetype ''/'__StaticArrayInitTypeSize=12' E429CCA3F703A39CC5954A6572FEC9086135B34E at I_00002DD4
+ .field static assembly initonly valuetype ''/'__StaticArrayInitTypeSize=12' '0F3DD643C5167ACFC541F72809FFF828A6E41494' at I_00002DF8
+ .field static assembly initonly valuetype ''/'__StaticArrayInitTypeSize=12' E429CCA3F703A39CC5954A6572FEC9086135B34E at I_00002E08
} // end of class ''
// =============================================================
-.data cil I_00002DC4 = bytearray (
+.data cil I_00002DF8 = bytearray (
0A 00 00 00 09 00 00 00 08 00 00 00)
-.data cil I_00002DD4 = bytearray (
+.data cil I_00002E04 = int8[4]
+.data cil I_00002E08 = bytearray (
01 00 00 00 02 00 00 00 03 00 00 00)
// *********** DISASSEMBLY COMPLETE ***********************
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.roslyn.il
index f8f4f8145..ec8a8e11d 100644
--- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.roslyn.il
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.roslyn.il
@@ -78,7 +78,7 @@
.method private hidebysig instance void
SimpleTests() cil managed
{
- // Code size 70 (0x46)
+ // Code size 86 (0x56)
.maxstack 3
IL_0000: nop
IL_0001: ldarg.0
@@ -109,7 +109,15 @@
IL_003a: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_003f: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.OptionalArguments::Decimal(valuetype [mscorlib]System.Decimal)
IL_0044: nop
- IL_0045: ret
+ IL_0045: ldarg.0
+ IL_0046: ldc.i4.1
+ IL_0047: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.OptionalArguments::NamedArgument(bool)
+ IL_004c: nop
+ IL_004d: ldarg.0
+ IL_004e: ldc.i4.0
+ IL_004f: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.OptionalArguments::NamedArgument(bool)
+ IL_0054: nop
+ IL_0055: ret
} // end of method OptionalArguments::SimpleTests
.method private hidebysig instance void
@@ -449,6 +457,15 @@
IL_0001: ret
} // end of method OptionalArguments::OnlyDifferenceIsLastArgumentCastNecessary
+ .method private hidebysig instance void
+ NamedArgument(bool flag) cil managed
+ {
+ // Code size 2 (0x2)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ret
+ } // end of method OptionalArguments::NamedArgument
+
.method private hidebysig instance string
Get([out] int32& a) cil managed
{
@@ -472,15 +489,15 @@
.size 12
} // end of class '__StaticArrayInitTypeSize=12'
- .field static assembly initonly valuetype ''/'__StaticArrayInitTypeSize=12' '0F3DD643C5167ACFC541F72809FFF828A6E41494' at I_00002DF4
- .field static assembly initonly valuetype ''/'__StaticArrayInitTypeSize=12' E429CCA3F703A39CC5954A6572FEC9086135B34E at I_00002E04
+ .field static assembly initonly valuetype ''/'__StaticArrayInitTypeSize=12' '0F3DD643C5167ACFC541F72809FFF828A6E41494' at I_00002E2C
+ .field static assembly initonly valuetype ''/'__StaticArrayInitTypeSize=12' E429CCA3F703A39CC5954A6572FEC9086135B34E at I_00002E3C
} // end of class ''
// =============================================================
-.data cil I_00002DF4 = bytearray (
+.data cil I_00002E2C = bytearray (
0A 00 00 00 09 00 00 00 08 00 00 00)
-.data cil I_00002E04 = bytearray (
+.data cil I_00002E3C = bytearray (
01 00 00 00 02 00 00 00 03 00 00 00)
// *********** DISASSEMBLY COMPLETE ***********************
diff --git a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs
index c395abd46..4bd91c498 100644
--- a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs
+++ b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs
@@ -593,7 +593,7 @@ namespace ICSharpCode.Decompiler.CSharp
parameter = method.Parameters[i - firstParamIndex];
}
var arg = expressionBuilder.Translate(callArguments[i], parameter.Type);
- if (IsPrimitiveValueThatShouldHaveNamedArgument(arg, method)) {
+ if (IsPrimitiveValueThatShouldBeNamedArgument(arg, method, parameter)) {
isPrimitiveValue.Set(arguments.Count);
}
if (IsOptionalArgument(parameter, arg)) {
@@ -644,11 +644,11 @@ namespace ICSharpCode.Decompiler.CSharp
return list;
}
- private bool IsPrimitiveValueThatShouldHaveNamedArgument(TranslatedExpression arg, IMethod method)
+ private bool IsPrimitiveValueThatShouldBeNamedArgument(TranslatedExpression arg, IMethod method, IParameter p)
{
if (!arg.ResolveResult.IsCompileTimeConstant || method.DeclaringType.IsKnownType(KnownTypeCode.NullableOfT))
return false;
- return arg.ResolveResult.Type.IsKnownType(KnownTypeCode.Boolean);
+ return p.Type.IsKnownType(KnownTypeCode.Boolean);
}
private bool TransformParamsArgument(ExpectedTargetDetails expectedTargetDetails, ResolveResult targetResolveResult,
@@ -714,8 +714,7 @@ namespace ICSharpCode.Decompiler.CSharp
|| a.AttributeType.IsKnownType(KnownAttribute.CallerFilePath)
|| a.AttributeType.IsKnownType(KnownAttribute.CallerLineNumber)))
return false;
- return (parameter.ConstantValue == null && arg.ResolveResult.ConstantValue == null)
- || (parameter.ConstantValue != null && parameter.ConstantValue.Equals(arg.ResolveResult.ConstantValue));
+ return object.Equals(parameter.ConstantValue, arg.ResolveResult.ConstantValue);
}
[Flags]
diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
index bef9069ee..1123ba85e 100644
--- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
+++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
@@ -370,25 +370,50 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override TranslatedExpression VisitLdcI4(LdcI4 inst, TranslationContext context)
{
- string literalValue = null;
- if (ShouldDisplayAsHex(inst.Value, inst.Parent)) {
- literalValue = $"0x{inst.Value:X}";
+ ResolveResult rr;
+ if (context.TypeHint.GetSign() == Sign.Unsigned) {
+ rr = new ConstantResolveResult(
+ compilation.FindType(KnownTypeCode.UInt32),
+ unchecked((uint)inst.Value)
+ );
+ } else {
+ rr = new ConstantResolveResult(
+ compilation.FindType(KnownTypeCode.Int32),
+ inst.Value
+ );
+ }
+ rr = AdjustConstantToType(rr, context.TypeHint);
+ astBuilder.PrintIntegralValuesAsHex = ShouldDisplayAsHex(inst.Value, inst.Parent);
+ try {
+ return ConvertConstantValue(rr, allowImplicitConversion: true)
+ .WithILInstruction(inst);
+ } finally {
+ astBuilder.PrintIntegralValuesAsHex = false;
}
- var expr = new PrimitiveExpression(inst.Value, literalValue)
- .WithILInstruction(inst)
- .WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), inst.Value));
- return AdjustConstantExpressionToType(expr, context.TypeHint);
}
protected internal override TranslatedExpression VisitLdcI8(LdcI8 inst, TranslationContext context)
{
- string literalValue = null;
- if (ShouldDisplayAsHex(inst.Value, inst.Parent)) {
- literalValue = $"0x{inst.Value:X}";
+ ResolveResult rr;
+ if (context.TypeHint.GetSign() == Sign.Unsigned) {
+ rr = new ConstantResolveResult(
+ compilation.FindType(KnownTypeCode.UInt64),
+ unchecked((ulong)inst.Value)
+ );
+ } else {
+ rr = new ConstantResolveResult(
+ compilation.FindType(KnownTypeCode.Int64),
+ inst.Value
+ );
+ }
+ rr = AdjustConstantToType(rr, context.TypeHint);
+ astBuilder.PrintIntegralValuesAsHex = ShouldDisplayAsHex(inst.Value, inst.Parent);
+ try {
+ return ConvertConstantValue(rr, allowImplicitConversion: true)
+ .WithILInstruction(inst);
+ } finally {
+ astBuilder.PrintIntegralValuesAsHex = false;
}
- return new PrimitiveExpression(inst.Value, literalValue)
- .WithILInstruction(inst)
- .WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int64), inst.Value));
}
private bool ShouldDisplayAsHex(long value, ILInstruction parent)
@@ -2354,22 +2379,39 @@ namespace ICSharpCode.Decompiler.CSharp
/// convert the expression into the target type.
/// Otherwise, returns the expression unmodified.
///
- TranslatedExpression AdjustConstantExpressionToType(TranslatedExpression expr, IType type)
+ TranslatedExpression AdjustConstantExpressionToType(TranslatedExpression expr, IType typeHint)
{
- if (!expr.ResolveResult.IsCompileTimeConstant) {
+ var newRR = AdjustConstantToType(expr.ResolveResult, typeHint);
+ if (newRR == expr.ResolveResult) {
return expr;
+ } else {
+ return ConvertConstantValue(newRR, allowImplicitConversion: true).WithILInstruction(expr.ILInstructions);
+ }
+ }
+
+ private ResolveResult AdjustConstantToType(ResolveResult rr, IType typeHint)
+ {
+ if (!rr.IsCompileTimeConstant) {
+ return rr;
+ }
+ typeHint = NullableType.GetUnderlyingType(typeHint);
+ if (rr.Type.Equals(typeHint)) {
+ return rr;
}
- type = NullableType.GetUnderlyingType(type);
- if (type.IsKnownType(KnownTypeCode.Boolean)
- && (object.Equals(expr.ResolveResult.ConstantValue, 0) || object.Equals(expr.ResolveResult.ConstantValue, 1))) {
- return expr.ConvertToBoolean(this);
- } else if (type.Kind == TypeKind.Enum || type.IsKnownType(KnownTypeCode.Char)) {
- var castRR = resolver.WithCheckForOverflow(true).ResolveCast(type, expr.ResolveResult);
+ // Convert to type hint, if this is possible without loss of accuracy
+ if (typeHint.IsKnownType(KnownTypeCode.Boolean)) {
+ if (object.Equals(rr.ConstantValue, 0) || object.Equals(rr.ConstantValue, 0u)) {
+ rr = new ConstantResolveResult(typeHint, false);
+ } else if (object.Equals(rr.ConstantValue, 1) || object.Equals(rr.ConstantValue, 1u)) {
+ rr = new ConstantResolveResult(typeHint, true);
+ }
+ } else if (typeHint.Kind == TypeKind.Enum || typeHint.IsKnownType(KnownTypeCode.Char) || typeHint.IsCSharpSmallIntegerType()) {
+ var castRR = resolver.WithCheckForOverflow(true).ResolveCast(typeHint, rr);
if (castRR.IsCompileTimeConstant && !castRR.IsError) {
- return ConvertConstantValue(castRR).WithILInstruction(expr.ILInstructions);
+ rr = castRR;
}
}
- return expr;
+ return rr;
}
protected internal override TranslatedExpression VisitNullCoalescingInstruction(NullCoalescingInstruction inst, TranslationContext context)
diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
index 8dd66433f..575306478 100644
--- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
+++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
@@ -186,8 +186,14 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
/// The default value is true.
///
public bool UseSpecialConstants { get; set; }
+
+ ///
+ /// Controls if integral constants should be printed in hexadecimal format.
+ /// The default value is false.
+ ///
+ public bool PrintIntegralValuesAsHex { get; set; }
#endregion
-
+
#region Convert Type
public AstType ConvertType(IType type)
{
@@ -715,7 +721,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
constantValue = CSharpPrimitiveCast.Cast(TypeCode.Int32, constantValue, false);
literalType = type.GetDefinition().Compilation.FindType(KnownTypeCode.Int32);
}
- expr = new PrimitiveExpression(constantValue);
+ string literalValue = null;
+ if (PrintIntegralValuesAsHex) {
+ literalValue = $"0x{constantValue:X}";
+ }
+ expr = new PrimitiveExpression(constantValue, literalValue);
if (AddResolveResultAnnotations)
expr.AddAnnotation(new ConstantResolveResult(literalType, constantValue));
if (smallInteger && !type.Equals(expectedType)) {
diff --git a/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs b/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
index 070081d8f..bbba0455b 100644
--- a/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
@@ -216,7 +216,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
///
/// Gets whether the type is the specified known type.
- /// For generic known types, this returns true any parameterization of the type (and also for the definition itself).
+ /// For generic known types, this returns true for any parameterization of the type (and also for the definition itself).
///
public static bool IsKnownType(this IType type, KnownTypeCode knownType)
{
@@ -226,7 +226,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
///
/// Gets whether the type is the specified known type.
- /// For generic known types, this returns true any parameterization of the type (and also for the definition itself).
+ /// For generic known types, this returns true for any parameterization of the type (and also for the definition itself).
///
internal static bool IsKnownType(this IType type, KnownAttribute knownType)
{
diff --git a/ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs b/ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs
index f406aa36e..8663a7926 100644
--- a/ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs
@@ -116,7 +116,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
///
/// Gets whether the type is a C# small integer type: byte, sbyte, short or ushort.
///
- /// Unlike the ILAst, C# does not consider bool or enums to be small integers.
+ /// Unlike the ILAst, C# does not consider bool, char or enums to be small integers.
///
public static bool IsCSharpSmallIntegerType(this IType type)
{