Browse Source

SwitchOnNullableTransform: Fix another special case produced by the Roslyn compiler.

pull/946/head
Siegfried Pammer 8 years ago
parent
commit
9630acd8b7
  1. 26
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs
  2. 80
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.il
  3. 72
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.il
  4. 45
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.roslyn.il
  5. 54
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.roslyn.il
  6. 41
      ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs

26
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs

@ -60,19 +60,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -60,19 +60,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
}
//public static bool? SwitchOverNullableEnum(State? state)
//{
// switch (state) {
// case State.False:
// return false;
// case State.True:
// return true;
// case State.Null:
// return null;
// default:
// throw new InvalidOperationException();
// }
//}
public static bool? SwitchOverNullableEnum(State? state)
{
switch (state) {
case State.False:
return false;
case State.True:
return true;
case State.Null:
return null;
default:
throw new InvalidOperationException();
}
}
public static string SparseIntegerSwitch(int i)
{

80
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.il

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly mhfw1ujx
.assembly o03zflju
{
.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.
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module mhfw1ujx.dll
// MVID: {2E35825E-3352-4C5E-B230-3B3F7055B304}
.module o03zflju.dll
// MVID: {0EF64C57-A49E-4138-9C3F-BDAB86B2E450}
.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
// Image base: 0x005A0000
// Image base: 0x01330000
// =============== CLASS MEMBERS DECLARATION ===================
@ -142,6 +142,52 @@ @@ -142,6 +142,52 @@
IL_0034: ret
} // end of method Switch::SwitchOverNullableBool
.method public hidebysig static valuetype [mscorlib]System.Nullable`1<bool>
SwitchOverNullableEnum(valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State> state) cil managed
{
// Code size 75 (0x4b)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<bool> V_0,
valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State V_1,
valuetype [mscorlib]System.Nullable`1<bool> V_2)
IL_0000: nop
IL_0001: ldarga.s state
IL_0003: dup
IL_0004: call instance !0 valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State>::GetValueOrDefault()
IL_0009: stloc.1
IL_000a: call instance bool valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State>::get_HasValue()
IL_000f: brfalse.s IL_0043
IL_0011: ldloc.1
IL_0012: switch (
IL_0025,
IL_002e,
IL_0037)
IL_0023: br.s IL_0043
IL_0025: ldc.i4.0
IL_0026: newobj instance void valuetype [mscorlib]System.Nullable`1<bool>::.ctor(!0)
IL_002b: stloc.0
IL_002c: br.s IL_0049
IL_002e: ldc.i4.1
IL_002f: newobj instance void valuetype [mscorlib]System.Nullable`1<bool>::.ctor(!0)
IL_0034: stloc.0
IL_0035: br.s IL_0049
IL_0037: ldloca.s V_2
IL_0039: initobj valuetype [mscorlib]System.Nullable`1<bool>
IL_003f: ldloc.2
IL_0040: stloc.0
IL_0041: br.s IL_0049
IL_0043: newobj instance void [mscorlib]System.InvalidOperationException::.ctor()
IL_0048: throw
IL_0049: ldloc.0
IL_004a: ret
} // end of method Switch::SwitchOverNullableEnum
.method public hidebysig static string
SparseIntegerSwitch(int32 i) cil managed
{
@ -834,7 +880,7 @@ @@ -834,7 +880,7 @@
IL_0015: brfalse IL_00e9
IL_001a: volatile.
IL_001c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000c-1'
IL_001c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000d-1'
IL_0021: brtrue.s IL_0084
IL_0023: ldc.i4.7
@ -875,9 +921,9 @@ @@ -875,9 +921,9 @@
IL_0078: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1)
IL_007d: volatile.
IL_007f: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000c-1'
IL_007f: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000d-1'
IL_0084: volatile.
IL_0086: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000c-1'
IL_0086: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000d-1'
IL_008b: ldloc.1
IL_008c: ldloca.s V_2
IL_008e: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -949,7 +995,7 @@ @@ -949,7 +995,7 @@
IL_0013: brfalse IL_0158
IL_0018: volatile.
IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000d-1'
IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000e-1'
IL_001f: brtrue IL_00b8
IL_0024: ldc.i4.s 11
@ -1010,9 +1056,9 @@ @@ -1010,9 +1056,9 @@
IL_00ac: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1)
IL_00b1: volatile.
IL_00b3: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000d-1'
IL_00b3: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000e-1'
IL_00b8: volatile.
IL_00ba: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x600000d-1'
IL_00ba: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x600000e-1'
IL_00bf: ldloc.1
IL_00c0: ldloca.s V_2
IL_00c2: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -1297,7 +1343,7 @@ @@ -1297,7 +1343,7 @@
IL_0030: brfalse IL_0121
IL_0035: volatile.
IL_0037: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x6000012-1'
IL_0037: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x6000013-1'
IL_003c: brtrue.s IL_0093
IL_003e: ldc.i4.6
@ -1333,9 +1379,9 @@ @@ -1333,9 +1379,9 @@
IL_0087: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1)
IL_008c: volatile.
IL_008e: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x6000012-1'
IL_008e: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x6000013-1'
IL_0093: volatile.
IL_0095: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'::'$$method0x6000012-1'
IL_0095: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'::'$$method0x6000013-1'
IL_009a: ldloc.s V_5
IL_009c: ldloca.s V_6
IL_009e: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -1562,14 +1608,14 @@ @@ -1562,14 +1608,14 @@
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch
.class private auto ansi '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'
.class private auto ansi '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x600000c-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x600000d-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000012-1'
} // end of class '<PrivateImplementationDetails>{2E35825E-3352-4C5E-B230-3B3F7055B304}'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x600000e-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000013-1'
} // end of class '<PrivateImplementationDetails>{0EF64C57-A49E-4138-9C3F-BDAB86B2E450}'
// =============================================================

72
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.il

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly okac2jza
.assembly pryqrprl
{
.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.
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module okac2jza.dll
// MVID: {7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}
.module pryqrprl.dll
// MVID: {FFEEBB9C-152A-467A-A4B4-51CF03878E20}
.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
// Image base: 0x01A40000
// Image base: 0x00B70000
// =============== CLASS MEMBERS DECLARATION ===================
@ -126,6 +126,44 @@ @@ -126,6 +126,44 @@
IL_002b: throw
} // end of method Switch::SwitchOverNullableBool
.method public hidebysig static valuetype [mscorlib]System.Nullable`1<bool>
SwitchOverNullableEnum(valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State> state) cil managed
{
// Code size 66 (0x42)
.maxstack 2
.locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State V_0,
valuetype [mscorlib]System.Nullable`1<bool> V_1)
IL_0000: ldarga.s state
IL_0002: dup
IL_0003: call instance !0 valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State>::GetValueOrDefault()
IL_0008: stloc.0
IL_0009: call instance bool valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State>::get_HasValue()
IL_000e: brfalse.s IL_003c
IL_0010: ldloc.0
IL_0011: switch (
IL_0024,
IL_002b,
IL_0032)
IL_0022: br.s IL_003c
IL_0024: ldc.i4.0
IL_0025: newobj instance void valuetype [mscorlib]System.Nullable`1<bool>::.ctor(!0)
IL_002a: ret
IL_002b: ldc.i4.1
IL_002c: newobj instance void valuetype [mscorlib]System.Nullable`1<bool>::.ctor(!0)
IL_0031: ret
IL_0032: ldloca.s V_1
IL_0034: initobj valuetype [mscorlib]System.Nullable`1<bool>
IL_003a: ldloc.1
IL_003b: ret
IL_003c: newobj instance void [mscorlib]System.InvalidOperationException::.ctor()
IL_0041: throw
} // end of method Switch::SwitchOverNullableEnum
.method public hidebysig static string
SparseIntegerSwitch(int32 i) cil managed
{
@ -711,7 +749,7 @@ @@ -711,7 +749,7 @@
IL_0013: brfalse IL_00db
IL_0018: volatile.
IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000c-1'
IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000d-1'
IL_001f: brtrue.s IL_0082
IL_0021: ldc.i4.7
@ -752,9 +790,9 @@ @@ -752,9 +790,9 @@
IL_0076: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1)
IL_007b: volatile.
IL_007d: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000c-1'
IL_007d: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000d-1'
IL_0082: volatile.
IL_0084: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000c-1'
IL_0084: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000d-1'
IL_0089: ldloc.0
IL_008a: ldloca.s V_1
IL_008c: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -812,7 +850,7 @@ @@ -812,7 +850,7 @@
IL_0011: brfalse IL_013d
IL_0016: volatile.
IL_0018: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000d-1'
IL_0018: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000e-1'
IL_001d: brtrue IL_00b6
IL_0022: ldc.i4.s 11
@ -873,9 +911,9 @@ @@ -873,9 +911,9 @@
IL_00aa: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1)
IL_00af: volatile.
IL_00b1: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000d-1'
IL_00b1: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000e-1'
IL_00b6: volatile.
IL_00b8: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x600000d-1'
IL_00b8: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x600000e-1'
IL_00bd: ldloc.0
IL_00be: ldloca.s V_1
IL_00c0: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -1099,7 +1137,7 @@ @@ -1099,7 +1137,7 @@
IL_002d: brfalse IL_0115
IL_0032: volatile.
IL_0034: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x6000012-1'
IL_0034: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x6000013-1'
IL_0039: brtrue.s IL_0090
IL_003b: ldc.i4.6
@ -1135,9 +1173,9 @@ @@ -1135,9 +1173,9 @@
IL_0084: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1)
IL_0089: volatile.
IL_008b: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x6000012-1'
IL_008b: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x6000013-1'
IL_0090: volatile.
IL_0092: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'::'$$method0x6000012-1'
IL_0092: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'::'$$method0x6000013-1'
IL_0097: ldloc.s V_5
IL_0099: ldloca.s V_6
IL_009b: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -1331,14 +1369,14 @@ @@ -1331,14 +1369,14 @@
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch
.class private auto ansi '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'
.class private auto ansi '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x600000c-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x600000d-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000012-1'
} // end of class '<PrivateImplementationDetails>{7ED4313F-4304-4C85-87F6-5AD4A6E6AA1F}'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x600000e-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000013-1'
} // end of class '<PrivateImplementationDetails>{FFEEBB9C-152A-467A-A4B4-51CF03878E20}'
// =============================================================

45
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.roslyn.il

@ -25,14 +25,14 @@ @@ -25,14 +25,14 @@
.ver 0:0:0:0
}
.module Switch.dll
// MVID: {6F3B5958-B8BE-48C6-82B8-5D3026DEACD1}
// MVID: {5D628BA5-FC59-43EC-A162-63729510F134}
.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
// Image base: 0x03160000
// Image base: 0x01390000
// =============== CLASS MEMBERS DECLARATION ===================
@ -136,6 +136,47 @@ @@ -136,6 +136,47 @@
IL_0027: throw
} // end of method Switch::SwitchOverNullableBool
.method public hidebysig static valuetype [mscorlib]System.Nullable`1<bool>
SwitchOverNullableEnum(valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State> state) cil managed
{
// Code size 69 (0x45)
.maxstack 1
.locals init (valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State> V_0,
valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State V_1,
valuetype [mscorlib]System.Nullable`1<bool> V_2)
IL_0000: ldarg.0
IL_0001: stloc.0
IL_0002: ldloca.s V_0
IL_0004: call instance bool valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State>::get_HasValue()
IL_0009: brfalse.s IL_003f
IL_000b: ldloca.s V_0
IL_000d: call instance !0 valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State>::GetValueOrDefault()
IL_0012: stloc.1
IL_0013: ldloc.1
IL_0014: switch (
IL_0027,
IL_002e,
IL_0035)
IL_0025: br.s IL_003f
IL_0027: ldc.i4.0
IL_0028: newobj instance void valuetype [mscorlib]System.Nullable`1<bool>::.ctor(!0)
IL_002d: ret
IL_002e: ldc.i4.1
IL_002f: newobj instance void valuetype [mscorlib]System.Nullable`1<bool>::.ctor(!0)
IL_0034: ret
IL_0035: ldloca.s V_2
IL_0037: initobj valuetype [mscorlib]System.Nullable`1<bool>
IL_003d: ldloc.2
IL_003e: ret
IL_003f: newobj instance void [mscorlib]System.InvalidOperationException::.ctor()
IL_0044: throw
} // end of method Switch::SwitchOverNullableEnum
.method public hidebysig static string
SparseIntegerSwitch(int32 i) cil managed
{

54
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.roslyn.il

@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
.ver 0:0:0:0
}
.module Switch.dll
// MVID: {7ADDBD28-42D6-469D-B92D-065C803347D0}
// MVID: {EF7D776C-0F54-445C-8A74-2D49ADE35F46}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
@ -152,6 +152,58 @@ @@ -152,6 +152,58 @@
IL_0034: ret
} // end of method Switch::SwitchOverNullableBool
.method public hidebysig static valuetype [mscorlib]System.Nullable`1<bool>
SwitchOverNullableEnum(valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State> state) cil managed
{
// Code size 81 (0x51)
.maxstack 1
.locals init (valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State> V_0,
valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State> V_1,
valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State V_2,
valuetype [mscorlib]System.Nullable`1<bool> V_3,
valuetype [mscorlib]System.Nullable`1<bool> V_4)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.1
IL_0003: ldloc.1
IL_0004: stloc.0
IL_0005: ldloca.s V_0
IL_0007: call instance bool valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State>::get_HasValue()
IL_000c: brfalse.s IL_0049
IL_000e: ldloca.s V_0
IL_0010: call instance !0 valuetype [mscorlib]System.Nullable`1<valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State>::GetValueOrDefault()
IL_0015: stloc.2
IL_0016: ldloc.2
IL_0017: switch (
IL_002a,
IL_0033,
IL_003c)
IL_0028: br.s IL_0049
IL_002a: ldc.i4.0
IL_002b: newobj instance void valuetype [mscorlib]System.Nullable`1<bool>::.ctor(!0)
IL_0030: stloc.3
IL_0031: br.s IL_004f
IL_0033: ldc.i4.1
IL_0034: newobj instance void valuetype [mscorlib]System.Nullable`1<bool>::.ctor(!0)
IL_0039: stloc.3
IL_003a: br.s IL_004f
IL_003c: ldloca.s V_4
IL_003e: initobj valuetype [mscorlib]System.Nullable`1<bool>
IL_0044: ldloc.s V_4
IL_0046: stloc.3
IL_0047: br.s IL_004f
IL_0049: newobj instance void [mscorlib]System.InvalidOperationException::.ctor()
IL_004e: throw
IL_004f: ldloc.3
IL_0050: ret
} // end of method Switch::SwitchOverNullableEnum
.method public hidebysig static string
SparseIntegerSwitch(int32 i) cil managed
{

41
ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs

@ -142,22 +142,43 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -142,22 +142,43 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!condition.MatchLogicNot(out var getHasValue) || !NullableLiftingTransform.MatchHasValueCall(getHasValue, out ILVariable target1) || target1 != tmp)
return false;
// match second block: switchBlock
// note: I have seen cases where switchVar is inlined into the switch.
// stloc switchVar(call GetValueOrDefault(ldloca tmp))
// switch (ldloc switchVar) {
// case [0..1): br caseBlock1
// ... more cases ...
// case [long.MinValue..0),[1..5),[6..10),[11..long.MaxValue]: br defaultBlock
// }
if (switchBlock.Instructions.Count != 2 || switchBlock.IncomingEdgeCount != 1)
return false;
if (!switchBlock.Instructions[0].MatchStLoc(out var switchVar, out var getValueOrDefault))
return false;
if (!switchVar.IsSingleDefinition || switchVar.LoadCount != 1)
return false;
if (!NullableLiftingTransform.MatchGetValueOrDefault(getValueOrDefault, tmp))
return false;
if (!(switchBlock.Instructions[1] is SwitchInstruction switchInst))
return false;
if (switchBlock.IncomingEdgeCount != 1)
return false;
SwitchInstruction switchInst;
switch (switchBlock.Instructions.Count) {
case 2: {
// this is the normal case described by the pattern above
if (!switchBlock.Instructions[0].MatchStLoc(out var switchVar, out var getValueOrDefault))
return false;
if (!switchVar.IsSingleDefinition || switchVar.LoadCount != 1)
return false;
if (!NullableLiftingTransform.MatchGetValueOrDefault(getValueOrDefault, tmp))
return false;
if (!(switchBlock.Instructions[1] is SwitchInstruction si))
return false;
switchInst = si;
break;
}
case 1: {
// this is the special case where `call GetValueOrDefault(ldloca tmp)` is inlined into the switch.
if (!(switchBlock.Instructions[0] is SwitchInstruction si))
return false;
if (!NullableLiftingTransform.MatchGetValueOrDefault(si.Value, tmp))
return false;
switchInst = si;
break;
}
default: {
return false;
}
}
newSwitch = BuildLiftedSwitch(nullCaseBlock, switchInst, switchValue);
return true;
}

Loading…
Cancel
Save