Browse Source

Fix #2182: Ensure that all labels generated by StatementBuilder are unique.

pull/2157/head
Siegfried Pammer 5 years ago
parent
commit
e7cb27a134
  1. 31
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

31
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -287,7 +287,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -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 @@ -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);
}
/// <summary>Target container that a 'break;' statement would break out of</summary>
@ -1190,7 +1190,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -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 @@ -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 @@ -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 @@ -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 @@ -1350,6 +1350,25 @@ namespace ICSharpCode.Decompiler.CSharp
return blockStatement;
}
readonly Dictionary<Block, string> labels = new Dictionary<Block, string>();
readonly Dictionary<string, int> duplicateLabels = new Dictionary<string, int>();
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())

Loading…
Cancel
Save