Browse Source

Fix #1071: Sometimes uses Enumarator instead of Foreach

pull/1087/head
Siegfried Pammer 7 years ago
parent
commit
3b31930b85
  1. 2
      ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
  2. 15
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs
  3. 1946
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.mcs.il
  4. 1946
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.mcs.il
  5. 7
      ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs

2
ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

@ -159,7 +159,7 @@ namespace ICSharpCode.Decompiler.Tests
} }
[Test] [Test]
public void Loops([ValueSource("defaultOptions")] CSharpCompilerOptions cscOptions) public void Loops([ValueSource("defaultOptionsWithMcs")] CSharpCompilerOptions cscOptions)
{ {
RunForLibrary(cscOptions: cscOptions); RunForLibrary(cscOptions: cscOptions);
} }

15
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs

@ -252,6 +252,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
} }
#if MCS
[StructLayout(LayoutKind.Sequential, Size = 1)]
#endif
public struct DataItem public struct DataItem
{ {
public int Property { public int Property {
@ -457,12 +460,21 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public void ForEachBreakWhenFound(string name, ref StringComparison output) public void ForEachBreakWhenFound(string name, ref StringComparison output)
{ {
#if MCS
foreach (int value in Enum.GetValues(typeof(StringComparison))) {
if (((StringComparison)value).ToString() == name) {
output = (StringComparison)value;
break;
}
}
#else
foreach (StringComparison value in Enum.GetValues(typeof(StringComparison))) { foreach (StringComparison value in Enum.GetValues(typeof(StringComparison))) {
if (value.ToString() == name) { if (value.ToString() == name) {
output = value; output = value;
break; break;
} }
} }
#endif
} }
public void ForEachOverListOfStruct(List<DataItem> items, int value) public void ForEachOverListOfStruct(List<DataItem> items, int value)
@ -496,6 +508,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
} }
#if !MCS
public void ForEachOverMultiDimArray(int[,] items) public void ForEachOverMultiDimArray(int[,] items)
{ {
foreach (int value in items) { foreach (int value in items) {
@ -526,6 +539,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
#endif #endif
} }
#endif
#endregion #endregion
public void ForOverArray(string[] array) public void ForOverArray(string[] array)

1946
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.mcs.il

File diff suppressed because it is too large Load Diff

1946
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.opt.mcs.il

File diff suppressed because it is too large Load Diff

7
ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs

@ -233,6 +233,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} }
} else { } else {
ILInstruction target; ILInstruction target;
bool boxedValue = false;
if (isReference && checkInst is NullableRewrap rewrap) { if (isReference && checkInst is NullableRewrap rewrap) {
// the null check of reference types might have been transformed into "objVar?.Dispose();" // the null check of reference types might have been transformed into "objVar?.Dispose();"
if (!(rewrap.Argument is CallVirt cv)) if (!(rewrap.Argument is CallVirt cv))
@ -264,6 +265,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
target = cv.Arguments.FirstOrDefault(); target = cv.Arguments.FirstOrDefault();
if (target == null) if (target == null)
return false; return false;
if (target.MatchBox(out var newTarget, out var type) && type.Equals(objVar.Type)) {
boxedValue = type.IsReferenceType != true;
target = newTarget;
}
callVirt = cv; callVirt = cv;
} }
if (callVirt.Method.FullName != "System.IDisposable.Dispose") if (callVirt.Method.FullName != "System.IDisposable.Dispose")
@ -272,7 +277,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
if (callVirt.Arguments.Count != 1) if (callVirt.Arguments.Count != 1)
return false; return false;
return target.MatchLdLocRef(objVar) || (usingNull && callVirt.Arguments[0].MatchLdNull()); return target.MatchLdLocRef(objVar) || (boxedValue && target.MatchLdLoc(objVar)) || (usingNull && callVirt.Arguments[0].MatchLdNull());
} }
} }
} }

Loading…
Cancel
Save