From 15f638af9adb49591213412dcb8318cd4f8b357e Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Tue, 23 Jun 2020 23:35:15 +0200 Subject: [PATCH] Fix decompilation of switch where default section is a leave instruction. --- .../IL/Transforms/SwitchOnStringTransform.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs index a25588629..6385ee159 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs @@ -860,7 +860,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms var stringValues = new List<(string Value, ILInstruction TargetBlockOrLeave)>(); SwitchSection defaultSection = switchInst.Sections.MaxBy(s => s.Labels.Count()); - if (!defaultSection.Body.MatchBranch(out Block exitOrDefaultBlock)) + if (!(defaultSection.Body.MatchBranch(out Block exitOrDefaultBlock) || defaultSection.Body.MatchLeave(out _))) return false; foreach (var section in switchInst.Sections) { if (section == defaultSection) continue; @@ -895,7 +895,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms } context.Step(nameof(MatchRoslynSwitchOnString), switchValueLoad); - ((Branch)defaultSection.Body).TargetBlock = exitOrDefaultBlock; + if (exitOrDefaultBlock != null) { + // change TargetBlock in case it was modified by IsNullCheckInDefaultBlock() + ((Branch)defaultSection.Body).TargetBlock = exitOrDefaultBlock; + } ILInstruction switchValueInst = switchValueLoad; if (instructions == switchBlockInstructions) { // stloc switchValueLoadVariable(switchValue) @@ -974,6 +977,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms private bool IsNullCheckInDefaultBlock(ref Block exitOrDefaultBlock, ILVariable switchVar, out Block nullValueCaseBlock) { nullValueCaseBlock = null; + if (exitOrDefaultBlock == null) + return false; if (!exitOrDefaultBlock.Instructions[0].MatchIfInstruction(out var condition, out var thenBranch)) return false; if (!(condition.MatchCompEqualsNull(out var arg) && arg.MatchLdLoc(switchVar)))