Browse Source

Fix #1795: `InvalidCastException: Cast from Boolean to Int64 not supported` when decompiling enum with bool constants

pull/1820/head
Daniel Grunwald 6 years ago
parent
commit
7326a69823
  1. 2
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  2. 6
      ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs
  3. 19
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.cs
  4. 36
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.il
  5. 24
      ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs

2
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -60,6 +60,7 @@ @@ -60,6 +60,7 @@
<None Include="TestCases\Correctness\StackTests.il" />
<None Include="TestCases\Correctness\StackTypes.il" />
<None Include="TestCases\Correctness\Uninit.vb" />
<None Include="TestCases\ILPretty\WeirdEnums.il" />
<None Include="TestCases\ILPretty\ConstantBlobs.il" />
<None Include="TestCases\ILPretty\CS1xSwitch_Debug.il" />
<None Include="TestCases\ILPretty\CS1xSwitch_Release.il" />
@ -80,6 +81,7 @@ @@ -80,6 +81,7 @@
<ItemGroup>
<Compile Include="DisassemblerPrettyTestRunner.cs" />
<Compile Include="TestCases\Correctness\StringConcat.cs" />
<None Include="TestCases\ILPretty\WeirdEnums.cs" />
<Compile Include="TestCases\ILPretty\ConstantBlobs.cs" />
<None Include="TestCases\Pretty\AsyncStreams.cs" />
<None Include="TestCases\Pretty\AsyncUsing.cs" />

6
ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs

@ -198,6 +198,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -198,6 +198,12 @@ namespace ICSharpCode.Decompiler.Tests
Run(settings: new DecompilerSettings { RemoveDeadStores = true });
}
[Test]
public void WeirdEnums()
{
Run();
}
void Run([CallerMemberName] string testName = null, DecompilerSettings settings = null)
{
var ilFile = Path.Combine(TestCasePath, testName + ".il");

19
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.cs

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
using System;
namespace TestEnum
{
public enum BooleanEnum : bool
{
Min = false,
Zero = false,
One = true,
Max = byte.MaxValue
}
public enum NativeIntEnum : IntPtr
{
Zero = 0L,
One = 1L,
FortyTwo = 42L
}
}

36
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.il

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
// 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 BoolEnum
{
.ver 1:0:0:0
}
.module BoolEnum.exe
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00020003 // ILONLY 32BITPREFERRED
// Image base: 0x000001C4B6C90000
.class public auto ansi sealed TestEnum.BooleanEnum
extends [mscorlib]System.Enum
{
.field public specialname rtspecialname bool value__
.field public static literal valuetype TestEnum.BooleanEnum Min = bool(false)
.field public static literal valuetype TestEnum.BooleanEnum Zero = bool(false)
.field public static literal valuetype TestEnum.BooleanEnum One = bool(true)
.field public static literal valuetype TestEnum.BooleanEnum Max = uint8(255)
}
.class public auto ansi sealed TestEnum.NativeIntEnum
extends [mscorlib]System.Enum
{
.field public specialname rtspecialname native int value__
.field public static literal valuetype TestEnum.NativeIntEnum Zero = int64(0)
.field public static literal valuetype TestEnum.NativeIntEnum One = int64(1)
.field public static literal valuetype TestEnum.NativeIntEnum FortyTwo = int64(42)
}

24
ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs

@ -64,6 +64,7 @@ namespace ICSharpCode.Decompiler.Util @@ -64,6 +64,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (char)(float)input;
case TypeCode.Double: return (char)(double)input;
case TypeCode.Decimal: return (char)(decimal)input;
case TypeCode.Boolean: return (char)((bool)input ? 1 : 0);
}
break;
case TypeCode.SByte:
@ -79,6 +80,7 @@ namespace ICSharpCode.Decompiler.Util @@ -79,6 +80,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (sbyte)(float)input;
case TypeCode.Double: return (sbyte)(double)input;
case TypeCode.Decimal: return (sbyte)(decimal)input;
case TypeCode.Boolean: return (sbyte)((bool)input ? 1 : 0);
}
break;
case TypeCode.Byte:
@ -94,6 +96,7 @@ namespace ICSharpCode.Decompiler.Util @@ -94,6 +96,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (byte)(float)input;
case TypeCode.Double: return (byte)(double)input;
case TypeCode.Decimal: return (byte)(decimal)input;
case TypeCode.Boolean: return (byte)((bool)input ? 1 : 0);
}
break;
case TypeCode.Int16:
@ -109,6 +112,7 @@ namespace ICSharpCode.Decompiler.Util @@ -109,6 +112,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (short)(float)input;
case TypeCode.Double: return (short)(double)input;
case TypeCode.Decimal: return (short)(decimal)input;
case TypeCode.Boolean: return (short)((bool)input ? 1 : 0);
}
break;
case TypeCode.UInt16:
@ -124,6 +128,7 @@ namespace ICSharpCode.Decompiler.Util @@ -124,6 +128,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (ushort)(float)input;
case TypeCode.Double: return (ushort)(double)input;
case TypeCode.Decimal: return (ushort)(decimal)input;
case TypeCode.Boolean: return (ushort)((bool)input ? 1 : 0);
}
break;
case TypeCode.Int32:
@ -139,6 +144,7 @@ namespace ICSharpCode.Decompiler.Util @@ -139,6 +144,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (int)(float)input;
case TypeCode.Double: return (int)(double)input;
case TypeCode.Decimal: return (int)(decimal)input;
case TypeCode.Boolean: return (int)((bool)input ? 1 : 0);
}
break;
case TypeCode.UInt32:
@ -154,6 +160,7 @@ namespace ICSharpCode.Decompiler.Util @@ -154,6 +160,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (uint)(float)input;
case TypeCode.Double: return (uint)(double)input;
case TypeCode.Decimal: return (uint)(decimal)input;
case TypeCode.Boolean: return (uint)((bool)input ? 1 : 0);
}
break;
case TypeCode.Int64:
@ -169,6 +176,7 @@ namespace ICSharpCode.Decompiler.Util @@ -169,6 +176,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (long)(float)input;
case TypeCode.Double: return (long)(double)input;
case TypeCode.Decimal: return (long)(decimal)input;
case TypeCode.Boolean: return (long)((bool)input ? 1 : 0);
}
break;
case TypeCode.UInt64:
@ -184,6 +192,7 @@ namespace ICSharpCode.Decompiler.Util @@ -184,6 +192,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (ulong)(float)input;
case TypeCode.Double: return (ulong)(double)input;
case TypeCode.Decimal: return (ulong)(decimal)input;
case TypeCode.Boolean: return (ulong)((bool)input ? 1 : 0);
}
break;
case TypeCode.Single:
@ -199,6 +208,7 @@ namespace ICSharpCode.Decompiler.Util @@ -199,6 +208,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.UInt64: return (float)(ulong)input;
case TypeCode.Double: return (float)(double)input;
case TypeCode.Decimal: return (float)(decimal)input;
case TypeCode.Boolean: return (float)((bool)input ? 1 : 0);
}
break;
case TypeCode.Double:
@ -214,6 +224,7 @@ namespace ICSharpCode.Decompiler.Util @@ -214,6 +224,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.UInt64: return (double)(ulong)input;
case TypeCode.Single: return (double)(float)input;
case TypeCode.Decimal: return (double)(decimal)input;
case TypeCode.Boolean: return (double)((bool)input ? 1 : 0);
}
break;
case TypeCode.Decimal:
@ -229,6 +240,7 @@ namespace ICSharpCode.Decompiler.Util @@ -229,6 +240,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.UInt64: return (decimal)(ulong)input;
case TypeCode.Single: return (decimal)(float)input;
case TypeCode.Double: return (decimal)(double)input;
case TypeCode.Boolean: return (decimal)((bool)input ? 1 : 0);
}
break;
}
@ -256,6 +268,7 @@ namespace ICSharpCode.Decompiler.Util @@ -256,6 +268,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (char)(float)input;
case TypeCode.Double: return (char)(double)input;
case TypeCode.Decimal: return (char)(decimal)input;
case TypeCode.Boolean: return (char)((bool)input ? 1 : 0);
}
break;
case TypeCode.SByte:
@ -271,6 +284,7 @@ namespace ICSharpCode.Decompiler.Util @@ -271,6 +284,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (sbyte)(float)input;
case TypeCode.Double: return (sbyte)(double)input;
case TypeCode.Decimal: return (sbyte)(decimal)input;
case TypeCode.Boolean: return (sbyte)((bool)input ? 1 : 0);
}
break;
case TypeCode.Byte:
@ -286,6 +300,7 @@ namespace ICSharpCode.Decompiler.Util @@ -286,6 +300,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (byte)(float)input;
case TypeCode.Double: return (byte)(double)input;
case TypeCode.Decimal: return (byte)(decimal)input;
case TypeCode.Boolean: return (byte)((bool)input ? 1 : 0);
}
break;
case TypeCode.Int16:
@ -301,6 +316,7 @@ namespace ICSharpCode.Decompiler.Util @@ -301,6 +316,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (short)(float)input;
case TypeCode.Double: return (short)(double)input;
case TypeCode.Decimal: return (short)(decimal)input;
case TypeCode.Boolean: return (short)((bool)input ? 1 : 0);
}
break;
case TypeCode.UInt16:
@ -316,6 +332,7 @@ namespace ICSharpCode.Decompiler.Util @@ -316,6 +332,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (ushort)(float)input;
case TypeCode.Double: return (ushort)(double)input;
case TypeCode.Decimal: return (ushort)(decimal)input;
case TypeCode.Boolean: return (ushort)((bool)input ? 1 : 0);
}
break;
case TypeCode.Int32:
@ -331,6 +348,7 @@ namespace ICSharpCode.Decompiler.Util @@ -331,6 +348,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (int)(float)input;
case TypeCode.Double: return (int)(double)input;
case TypeCode.Decimal: return (int)(decimal)input;
case TypeCode.Boolean: return (int)((bool)input ? 1 : 0);
}
break;
case TypeCode.UInt32:
@ -346,6 +364,7 @@ namespace ICSharpCode.Decompiler.Util @@ -346,6 +364,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (uint)(float)input;
case TypeCode.Double: return (uint)(double)input;
case TypeCode.Decimal: return (uint)(decimal)input;
case TypeCode.Boolean: return (uint)((bool)input ? 1 : 0);
}
break;
case TypeCode.Int64:
@ -361,6 +380,7 @@ namespace ICSharpCode.Decompiler.Util @@ -361,6 +380,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (long)(float)input;
case TypeCode.Double: return (long)(double)input;
case TypeCode.Decimal: return (long)(decimal)input;
case TypeCode.Boolean: return (long)((bool)input ? 1 : 0);
}
break;
case TypeCode.UInt64:
@ -376,6 +396,7 @@ namespace ICSharpCode.Decompiler.Util @@ -376,6 +396,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.Single: return (ulong)(float)input;
case TypeCode.Double: return (ulong)(double)input;
case TypeCode.Decimal: return (ulong)(decimal)input;
case TypeCode.Boolean: return (ulong)((bool)input ? 1 : 0);
}
break;
case TypeCode.Single:
@ -391,6 +412,7 @@ namespace ICSharpCode.Decompiler.Util @@ -391,6 +412,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.UInt64: return (float)(ulong)input;
case TypeCode.Double: return (float)(double)input;
case TypeCode.Decimal: return (float)(decimal)input;
case TypeCode.Boolean: return (float)((bool)input ? 1 : 0);
}
break;
case TypeCode.Double:
@ -406,6 +428,7 @@ namespace ICSharpCode.Decompiler.Util @@ -406,6 +428,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.UInt64: return (double)(ulong)input;
case TypeCode.Single: return (double)(float)input;
case TypeCode.Decimal: return (double)(decimal)input;
case TypeCode.Boolean: return (double)((bool)input ? 1 : 0);
}
break;
case TypeCode.Decimal:
@ -421,6 +444,7 @@ namespace ICSharpCode.Decompiler.Util @@ -421,6 +444,7 @@ namespace ICSharpCode.Decompiler.Util
case TypeCode.UInt64: return (decimal)(ulong)input;
case TypeCode.Single: return (decimal)(float)input;
case TypeCode.Double: return (decimal)(double)input;
case TypeCode.Boolean: return (decimal)((bool)input ? 1 : 0);
}
break;
}

Loading…
Cancel
Save