Browse Source

Fix #1936: TransformDisplayClassUsage should remove copies of display-class references.

pull/1939/head
Siegfried Pammer 5 years ago
parent
commit
73e0f7c3ac
  1. 20
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/Capturing.cs
  2. 15
      ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs

20
ICSharpCode.Decompiler.Tests/TestCases/Correctness/Capturing.cs

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
{
@ -18,6 +19,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -18,6 +19,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
InsideLoopOverArray2();
NotWhileDueToVariableInsideLoop();
NotDoWhileDueToVariableInsideLoop();
Issue1936();
}
static void TestCase1()
@ -210,5 +212,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -210,5 +212,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
Console.WriteLine(f());
}
}
public static void Issue1936()
{
IEnumerable<object> outerCapture = null;
for (int i = 0; i < 10; i++) {
int innerCapture = 0;
Action a = (delegate {
List<object> list = new List<object>();
Console.WriteLine("before inc: " + innerCapture);
++innerCapture;
Console.WriteLine("after inc: " + innerCapture);
Console.WriteLine("before assign: " + outerCapture);
outerCapture = outerCapture == null ? list : outerCapture.Concat(list);
Console.WriteLine("after assign: " + outerCapture);
});
a.Invoke();
}
}
}
}

15
ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs

@ -309,9 +309,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -309,9 +309,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
base.VisitStLoc(inst);
if (inst.Variable.Kind == VariableKind.Local && inst.Variable.IsSingleDefinition && inst.Variable.LoadCount == 0 && inst.Value is StLoc) {
context.Step($"Remove unused variable assignment {inst.Variable.Name}", inst);
inst.ReplaceWith(inst.Value);
if (inst.Parent is Block && inst.Variable.IsSingleDefinition) {
if (inst.Variable.Kind == VariableKind.Local && inst.Variable.LoadCount == 0 && inst.Value is StLoc) {
context.Step($"Remove unused variable assignment {inst.Variable.Name}", inst);
inst.ReplaceWith(inst.Value);
return;
}
if (inst.Value.MatchLdLoc(out var displayClassVariable) && displayClasses.TryGetValue(displayClassVariable, out var displayClass)) {
context.Step($"Found copy-assignment of display-class variable {displayClassVariable.Name}", inst);
displayClasses.Add(inst.Variable, displayClass);
instructionsToRemove.Add(inst);
return;
}
}
}

Loading…
Cancel
Save