diff --git a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs index 3a3a0de24..316386d21 100644 --- a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs @@ -287,7 +287,7 @@ namespace ICSharpCode.Decompiler.CSharp { if (caseLabelMapping.ContainsKey(block)) continue; - lastSectionStatements.Add(new LabelStatement { Label = block.Label }); + lastSectionStatements.Add(new LabelStatement { Label = EnsureUniqueLabel(block) }); foreach (var nestedInst in block.Instructions) { var nestedStmt = Convert(nestedInst); @@ -355,7 +355,7 @@ namespace ICSharpCode.Decompiler.CSharp return new GotoCaseStatement() { LabelExpression = exprBuilder.ConvertConstantValue(label, allowImplicitConversion: true) } .WithILInstruction(inst); } - return new GotoStatement(inst.TargetLabel).WithILInstruction(inst); + return new GotoStatement(EnsureUniqueLabel(inst.TargetBlock)).WithILInstruction(inst); } /// Target container that a 'break;' statement would break out of @@ -1190,7 +1190,7 @@ namespace ICSharpCode.Decompiler.CSharp // We'll also remove any "continue;" in front of the label, as it's redundant. if (blockStatement.LastOrDefault() is ContinueStatement) blockStatement.Last().Remove(); - blockStatement.Add(new LabelStatement { Label = container.EntryPoint.Label }); + blockStatement.Add(new LabelStatement { Label = EnsureUniqueLabel(container.EntryPoint) }); } if (blockStatement.LastOrDefault() is ContinueStatement continueStmt2) @@ -1214,7 +1214,7 @@ namespace ICSharpCode.Decompiler.CSharp { // if there are branches to the condition block, that were not converted // to continue statements, we have to introduce an extra label. - blockStatement.Add(new LabelStatement { Label = continueTarget.Label }); + blockStatement.Add(new LabelStatement { Label = EnsureUniqueLabel(continueTarget) }); } DeclareLocalFunctions(currentFunction, container, blockStatement); if (blockStatement.Statements.Count == 0) @@ -1249,7 +1249,7 @@ namespace ICSharpCode.Decompiler.CSharp forStmt.Iterators.Add(Convert(continueTarget.Instructions[i])); } if (continueTarget.IncomingEdgeCount > continueCount) - blockStatement.Add(new LabelStatement { Label = continueTarget.Label }); + blockStatement.Add(new LabelStatement { Label = EnsureUniqueLabel(continueTarget) }); DeclareLocalFunctions(currentFunction, container, blockStatement); return forStmt; default: @@ -1309,7 +1309,7 @@ namespace ICSharpCode.Decompiler.CSharp if (block.IncomingEdgeCount > 1 || block != container.EntryPoint) { // If there are any incoming branches to this block, add a label: - blockStatement.Add(new LabelStatement { Label = block.Label }); + blockStatement.Add(new LabelStatement { Label = EnsureUniqueLabel(block) }); } foreach (var inst in block.Instructions) { @@ -1350,6 +1350,25 @@ namespace ICSharpCode.Decompiler.CSharp return blockStatement; } + readonly Dictionary labels = new Dictionary(); + readonly Dictionary duplicateLabels = new Dictionary(); + + string EnsureUniqueLabel(Block block) + { + if (labels.TryGetValue(block, out string label)) + return label; + if (!duplicateLabels.TryGetValue(block.Label, out int count)) + { + labels.Add(block, block.Label); + duplicateLabels.Add(block.Label, 1); + return block.Label; + } + label = $"{block.Label}_{count + 1}"; + duplicateLabels[block.Label]++; + labels.Add(block, label); + return label; + } + static bool IsFinalLeave(Leave leave) { if (!leave.Value.MatchNop())