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())