Browse Source

Handle roslyn generated sub instructions in partitioned C# switch statements

pull/1258/head
Chicken-Bones 7 years ago
parent
commit
9a3914fca9
  1. 18
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs
  2. 85
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.il
  3. 81
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.il
  4. 62
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.opt.roslyn.il
  5. 79
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.roslyn.il
  6. 26
      ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs

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

@ -105,6 +105,24 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -105,6 +105,24 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
}
public static void SparseIntegerSwitch2(int i)
{
switch (i) {
case 4:
case 10:
case 11:
case 13:
case 21:
case 29:
case 33:
case 49:
case 50:
case 55:
Console.WriteLine();
break;
}
}
public static string SwitchOverNullableInt(int? i)
{
switch (i) {

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

@ -293,6 +293,69 @@ @@ -293,6 +293,69 @@
IL_00d0: ret
} // end of method Switch::SparseIntegerSwitch
.method public hidebysig static void SparseIntegerSwitch2(int32 i) cil managed
{
// Code size 94 (0x5e)
.maxstack 2
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: ldc.i4.s 21
IL_0006: bgt.s IL_002c
IL_0008: ldloc.0
IL_0009: ldc.i4.4
IL_000a: beq.s IL_0055
IL_000c: ldloc.0
IL_000d: ldc.i4.s 10
IL_000f: sub
IL_0010: switch (
IL_0055,
IL_0055,
IL_005d,
IL_0055)
IL_0025: ldloc.0
IL_0026: ldc.i4.s 21
IL_0028: beq.s IL_0055
IL_002a: br.s IL_005d
IL_002c: ldloc.0
IL_002d: ldc.i4.s 33
IL_002f: bgt.s IL_003d
IL_0031: ldloc.0
IL_0032: ldc.i4.s 29
IL_0034: beq.s IL_0055
IL_0036: ldloc.0
IL_0037: ldc.i4.s 33
IL_0039: beq.s IL_0055
IL_003b: br.s IL_005d
IL_003d: ldloc.0
IL_003e: ldc.i4.s 49
IL_0040: sub
IL_0041: switch (
IL_0055,
IL_0055)
IL_004e: ldloc.0
IL_004f: ldc.i4.s 55
IL_0051: beq.s IL_0055
IL_0053: br.s IL_005d
IL_0055: call void [mscorlib]System.Console::WriteLine()
IL_005a: nop
IL_005b: br.s IL_005d
IL_005d: ret
} // end of method Switch::SparseIntegerSwitch2
.method public hidebysig static string
SwitchOverNullableInt(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
@ -876,7 +939,7 @@ @@ -876,7 +939,7 @@
IL_0015: brfalse IL_00e9
IL_001a: volatile.
IL_001c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000d-1'
IL_001c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000e-1'
IL_0021: brtrue.s IL_0084
IL_0023: ldc.i4.7
@ -917,9 +980,9 @@ @@ -917,9 +980,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>'::'$$method0x600000d-1'
IL_007f: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000e-1'
IL_0084: volatile.
IL_0086: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000d-1'
IL_0086: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000e-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,
@ -991,7 +1054,7 @@ @@ -991,7 +1054,7 @@
IL_0013: brfalse IL_0158
IL_0018: volatile.
IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000e-1'
IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000f-1'
IL_001f: brtrue IL_00b8
IL_0024: ldc.i4.s 11
@ -1052,9 +1115,9 @@ @@ -1052,9 +1115,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>'::'$$method0x600000e-1'
IL_00b3: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000f-1'
IL_00b8: volatile.
IL_00ba: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000e-1'
IL_00ba: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000f-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,
@ -1342,7 +1405,7 @@ @@ -1342,7 +1405,7 @@
IL_003b: brfalse IL_012c
IL_0040: volatile.
IL_0042: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000013-1'
IL_0042: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000014-1'
IL_0047: brtrue.s IL_009e
IL_0049: ldc.i4.6
@ -1378,9 +1441,9 @@ @@ -1378,9 +1441,9 @@
IL_0092: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1)
IL_0097: volatile.
IL_0099: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000013-1'
IL_0099: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000014-1'
IL_009e: volatile.
IL_00a0: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000013-1'
IL_00a0: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000014-1'
IL_00a5: ldloc.s V_5
IL_00a7: ldloca.s V_6
IL_00a9: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -1611,9 +1674,9 @@ @@ -1611,9 +1674,9 @@
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> '$$method0x600000d-1'
.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'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x600000f-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000014-1'
} // end of class '<PrivateImplementationDetails>'

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

@ -251,6 +251,65 @@ @@ -251,6 +251,65 @@
IL_00b4: ret
} // end of method Switch::SparseIntegerSwitch
.method public hidebysig static void SparseIntegerSwitch2(int32 i) cil managed
{
// Code size 87 (0x57)
.maxstack 2
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: ldc.i4.s 21
IL_0005: bgt.s IL_002a
IL_0007: ldloc.0
IL_0008: ldc.i4.4
IL_0009: beq.s IL_0051
IL_000b: ldloc.0
IL_000c: ldc.i4.s 10
IL_000e: sub
IL_000f: switch (
IL_0051,
IL_0051,
IL_0056,
IL_0051)
IL_0024: ldloc.0
IL_0025: ldc.i4.s 21
IL_0027: beq.s IL_0051
IL_0029: ret
IL_002a: ldloc.0
IL_002b: ldc.i4.s 33
IL_002d: bgt.s IL_003a
IL_002f: ldloc.0
IL_0030: ldc.i4.s 29
IL_0032: beq.s IL_0051
IL_0034: ldloc.0
IL_0035: ldc.i4.s 33
IL_0037: beq.s IL_0051
IL_0039: ret
IL_003a: ldloc.0
IL_003b: ldc.i4.s 49
IL_003d: sub
IL_003e: switch (
IL_0051,
IL_0051)
IL_004b: ldloc.0
IL_004c: ldc.i4.s 55
IL_004e: beq.s IL_0051
IL_0050: ret
IL_0051: call void [mscorlib]System.Console::WriteLine()
IL_0056: ret
} // end of method Switch::SparseIntegerSwitch2
.method public hidebysig static string
SwitchOverNullableInt(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{
@ -745,7 +804,7 @@ @@ -745,7 +804,7 @@
IL_0013: brfalse IL_00db
IL_0018: volatile.
IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000d-1'
IL_001a: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000e-1'
IL_001f: brtrue.s IL_0082
IL_0021: ldc.i4.7
@ -786,9 +845,9 @@ @@ -786,9 +845,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>'::'$$method0x600000d-1'
IL_007d: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000e-1'
IL_0082: volatile.
IL_0084: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000d-1'
IL_0084: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000e-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,
@ -846,7 +905,7 @@ @@ -846,7 +905,7 @@
IL_0011: brfalse IL_013d
IL_0016: volatile.
IL_0018: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000e-1'
IL_0018: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000f-1'
IL_001d: brtrue IL_00b6
IL_0022: ldc.i4.s 11
@ -907,9 +966,9 @@ @@ -907,9 +966,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>'::'$$method0x600000e-1'
IL_00b1: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000f-1'
IL_00b6: volatile.
IL_00b8: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000e-1'
IL_00b8: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x600000f-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,
@ -1135,7 +1194,7 @@ @@ -1135,7 +1194,7 @@
IL_0037: brfalse IL_011f
IL_003c: volatile.
IL_003e: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000013-1'
IL_003e: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000014-1'
IL_0043: brtrue.s IL_009a
IL_0045: ldc.i4.6
@ -1171,9 +1230,9 @@ @@ -1171,9 +1230,9 @@
IL_008e: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1)
IL_0093: volatile.
IL_0095: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000013-1'
IL_0095: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000014-1'
IL_009a: volatile.
IL_009c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000013-1'
IL_009c: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>'::'$$method0x6000014-1'
IL_00a1: ldloc.s V_5
IL_00a3: ldloca.s V_6
IL_00a5: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
@ -1371,9 +1430,9 @@ @@ -1371,9 +1430,9 @@
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> '$$method0x600000d-1'
.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'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x600000f-1'
.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x6000014-1'
} // end of class '<PrivateImplementationDetails>'

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

@ -269,6 +269,68 @@ @@ -269,6 +269,68 @@
IL_00b8: ret
} // end of method Switch::SparseIntegerSwitch
.method public hidebysig static void SparseIntegerSwitch2(int32 i) cil managed
{
// Code size 67 (0x43)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldc.i4.s 21
IL_0003: bgt.s IL_0021
IL_0005: ldarg.0
IL_0006: ldc.i4.s 11
IL_0008: bgt.s IL_0016
IL_000a: ldarg.0
IL_000b: ldc.i4.4
IL_000c: beq.s IL_003d
IL_000e: ldarg.0
IL_000f: ldc.i4.s 10
IL_0011: sub
IL_0012: ldc.i4.1
IL_0013: ble.un.s IL_003d
IL_0015: ret
IL_0016: ldarg.0
IL_0017: ldc.i4.s 13
IL_0019: beq.s IL_003d
IL_001b: ldarg.0
IL_001c: ldc.i4.s 21
IL_001e: beq.s IL_003d
IL_0020: ret
IL_0021: ldarg.0
IL_0022: ldc.i4.s 33
IL_0024: bgt.s IL_0031
IL_0026: ldarg.0
IL_0027: ldc.i4.s 29
IL_0029: beq.s IL_003d
IL_002b: ldarg.0
IL_002c: ldc.i4.s 33
IL_002e: beq.s IL_003d
IL_0030: ret
IL_0031: ldarg.0
IL_0032: ldc.i4.s 49
IL_0034: sub
IL_0035: ldc.i4.1
IL_0036: ble.un.s IL_003d
IL_0038: ldarg.0
IL_0039: ldc.i4.s 55
IL_003b: bne.un.s IL_0042
IL_003d: call void [mscorlib]System.Console::WriteLine()
IL_0042: ret
} // end of method Switch::SparseIntegerSwitch2
.method public hidebysig static string
SwitchOverNullableInt(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{

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

@ -325,6 +325,85 @@ @@ -325,6 +325,85 @@
IL_00e1: ret
} // end of method Switch::SparseIntegerSwitch
.method public hidebysig static void SparseIntegerSwitch2(int32 i) cil managed
{
// Code size 86 (0x56)
.maxstack 2
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: ldc.i4.s 21
IL_0006: bgt.s IL_002a
IL_0008: ldloc.0
IL_0009: ldc.i4.s 11
IL_000b: bgt.s IL_001c
IL_000d: ldloc.0
IL_000e: ldc.i4.4
IL_000f: beq.s IL_004d
IL_0011: br.s IL_0013
IL_0013: ldloc.0
IL_0014: ldc.i4.s 10
IL_0016: sub
IL_0017: ldc.i4.1
IL_0018: ble.un.s IL_004d
IL_001a: br.s IL_0055
IL_001c: ldloc.0
IL_001d: ldc.i4.s 13
IL_001f: beq.s IL_004d
IL_0021: br.s IL_0023
IL_0023: ldloc.0
IL_0024: ldc.i4.s 21
IL_0026: beq.s IL_004d
IL_0028: br.s IL_0055
IL_002a: ldloc.0
IL_002b: ldc.i4.s 33
IL_002d: bgt.s IL_003d
IL_002f: ldloc.0
IL_0030: ldc.i4.s 29
IL_0032: beq.s IL_004d
IL_0034: br.s IL_0036
IL_0036: ldloc.0
IL_0037: ldc.i4.s 33
IL_0039: beq.s IL_004d
IL_003b: br.s IL_0055
IL_003d: ldloc.0
IL_003e: ldc.i4.s 49
IL_0040: sub
IL_0041: ldc.i4.1
IL_0042: ble.un.s IL_004d
IL_0044: br.s IL_0046
IL_0046: ldloc.0
IL_0047: ldc.i4.s 55
IL_0049: beq.s IL_004d
IL_004b: br.s IL_0055
IL_004d: call void [mscorlib]System.Console::WriteLine()
IL_0052: nop
IL_0053: br.s IL_0055
IL_0055: ret
} // end of method Switch::SparseIntegerSwitch2
.method public hidebysig static string
SwitchOverNullableInt(valuetype [mscorlib]System.Nullable`1<int32> i) cil managed
{

26
ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs

@ -3,6 +3,7 @@ using System.Diagnostics; @@ -3,6 +3,7 @@ using System.Diagnostics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using System;
using System.Linq;
namespace ICSharpCode.Decompiler.IL.ControlFlow
{
@ -38,7 +39,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -38,7 +39,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
public bool ContainsILSwitch { get; private set; }
/// <summary>
/// Gets the sections that were detected by the previoous AnalyzeBlock() call.
/// Gets the sections that were detected by the previous AnalyzeBlock() call.
/// </summary>
public readonly List<KeyValuePair<LongSet, ILInstruction>> Sections = new List<KeyValuePair<LongSet, ILInstruction>>();
@ -230,15 +231,36 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -230,15 +231,36 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
return inst.MatchLdLoc(out switchVar);
}
bool MatchSwitchVar(ILInstruction inst, out long sub)
{
if (inst.MatchBinaryNumericInstruction(BinaryNumericOperator.Sub, out var left, out var right) && right.MatchLdcI(out sub))
return MatchSwitchVar(left);
sub = 0;
return MatchSwitchVar(inst);
}
/// <summary>
/// Shifts a LongInterval, treating long.MinValue and long.MaxValue like float.Positive/NegativeInfinity
/// </summary>
LongInterval ShiftInterval(LongInterval interval, long offset)
{
return new LongInterval(
interval.Start == long.MinValue ? long.MinValue : interval.Start + offset,
interval.End == long.MinValue ? long.MinValue : interval.End + offset);
}
/// <summary>
/// Analyzes the boolean condition, returning the set of values of the interesting
/// variable for which the condition evaluates to true.
/// </summary>
private bool AnalyzeCondition(ILInstruction condition, out LongSet trueValues)
{
if (condition is Comp comp && MatchSwitchVar(comp.Left) && comp.Right.MatchLdcI(out long val)) {
if (condition is Comp comp && MatchSwitchVar(comp.Left, out var sub) && comp.Right.MatchLdcI(out long val)) {
// if (comp(V OP val))
trueValues = MakeSetWhereComparisonIsTrue(comp.Kind, val, comp.Sign);
if (sub != 0)
trueValues = new LongSet(trueValues.Intervals.Select(i => ShiftInterval(i, sub)));
return true;
} else if (MatchSwitchVar(condition)) {
// if (ldloc V) --> branch for all values except 0

Loading…
Cancel
Save