Browse Source

Fix #1621: Add AllowUnreachableCases in switch analysis.

pull/1649/head
Siegfried Pammer 6 years ago
parent
commit
def681ccdf
  1. 23
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs
  2. 12
      ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs
  3. 2
      ICSharpCode.Decompiler/IL/ControlFlow/SwitchDetection.cs

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

@ -1145,5 +1145,28 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -1145,5 +1145,28 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
Console.WriteLine();
}
public static string Issue1621(int x)
{
if (x == 5) {
return "5";
}
switch (x) {
case 1:
return "1";
case 2:
case 6:
case 7:
return "2-6-7";
case 3:
return "3";
case 4:
return "4";
case 5:
return "unreachable";
default:
throw new Exception();
}
}
}
}

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

@ -28,10 +28,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -28,10 +28,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
/// <summary>
/// The variable to be used as the argument of the switch instruction.
/// </summary>
public ILVariable SwitchVariable
{
get { return switchVar; }
}
public ILVariable SwitchVariable => switchVar;
/// <summary>
/// Whether at least one the analyzed blocks contained an IL switch constructors.
@ -62,6 +59,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -62,6 +59,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
public Block RootBlock { get; private set; }
/// <summary>
/// Gets/sets whether to allow unreachable cases in switch instructions.
/// </summary>
public bool AllowUnreachableCases { get; set; }
/// <summary>
/// Analyze the last two statements in the block and see if they can be turned into a
/// switch instruction.
@ -180,6 +182,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -180,6 +182,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
foreach (var section in inst.Sections) {
var matchValues = section.Labels.AddOffset(offset).IntersectWith(inputValues);
if (!AllowUnreachableCases && matchValues.IsEmpty)
return false;
if (matchValues.Count() > 1 && section.Body.MatchBranch(out var targetBlock) && AnalyzeBlock(targetBlock, matchValues)) {
InnerBlocks.Add(targetBlock);
} else {

2
ICSharpCode.Decompiler/IL/ControlFlow/SwitchDetection.cs

@ -132,6 +132,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -132,6 +132,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
{
this.context = context;
analysis.AllowUnreachableCases = context.Settings.RemoveDeadCode;
foreach (var container in function.Descendants.OfType<BlockContainer>()) {
currentContainer = container;
controlFlowGraph = null;

Loading…
Cancel
Save