Browse Source

Fix #1642: Allow StackTypes I, I4, I8 and Unknown as switch value, convert Unknown and I to I8.

pull/1649/head
Siegfried Pammer 6 years ago
parent
commit
9c06d5c924
  1. 8
      ICSharpCode.Decompiler/IL/ControlFlow/SwitchDetection.cs
  2. 11
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

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

@ -158,13 +158,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -158,13 +158,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
void ProcessBlock(Block block, ref bool blockContainerNeedsCleanup)
{
bool analysisSuccess = analysis.AnalyzeBlock(block);
KeyValuePair<LongSet, ILInstruction> defaultSection;
if (analysisSuccess && UseCSharpSwitch(out defaultSection)) {
if (analysisSuccess && UseCSharpSwitch(out _)) {
// complex multi-block switch that can be combined into a single SwitchInstruction
ILInstruction switchValue = new LdLoc(analysis.SwitchVariable);
if (switchValue.ResultType == StackType.Unknown) {
Debug.Assert(switchValue.ResultType.IsIntegerType() || switchValue.ResultType == StackType.Unknown);
if (!(switchValue.ResultType == StackType.I4 || switchValue.ResultType == StackType.I8)) {
// switchValue must have a result type of either I4 or I8
switchValue = new Conv(switchValue, PrimitiveType.I8, false, TypeSystem.Sign.Signed);
switchValue = new Conv(switchValue, PrimitiveType.I8, false, Sign.Signed);
}
var sw = new SwitchInstruction(switchValue);
foreach (var section in analysis.Sections) {

11
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -62,6 +62,17 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -62,6 +62,17 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
protected internal override void VisitBlockContainer(BlockContainer container)
{
if (container.Kind == ContainerKind.Switch) {
// Special case for switch: Only visit the switch condition block.
var switchInst = (SwitchInstruction)container.EntryPoint.Instructions[0];
switchInst.Value.AcceptVisitor(this);
return;
}
base.VisitBlockContainer(container);
}
protected internal override void VisitBlock(Block block)
{
if (block.Kind == BlockKind.ControlFlow) {

Loading…
Cancel
Save