Browse Source

Fix #878: InvalidCastException in StatementBuilder.TransformToForeach

pull/879/head
Siegfried Pammer 8 years ago
parent
commit
692a1e8e35
  1. 27
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/Loops.cs
  2. 3
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  3. 6
      ICSharpCode.Decompiler/IL/DetectedLoop.cs

27
ICSharpCode.Decompiler.Tests/TestCases/Correctness/Loops.cs

@ -32,6 +32,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -32,6 +32,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
ForWithMultipleVariables();
DoubleForEachWithSameVariable(new[] { "a", "b", "c" });
ForeachExceptForNameCollision(new[] { 42, 43, 44, 45 });
NonGenericForeachWithReturnFallbackTest(new object[] { "a", 42, "b", 43 });
NonGenericForeachWithReturn(new object[] { "a", 42, "b", 43 });
ForeachWithReturn(new[] { 42, 43, 44, 45 });
}
public static void ForWithMultipleVariables()
@ -90,5 +93,29 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -90,5 +93,29 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
}
Console.WriteLine("After finally!");
}
public static object NonGenericForeachWithReturn(IEnumerable enumerable)
{
Console.WriteLine("NonGenericForeachWithReturn:");
foreach (var obj in enumerable) {
Console.WriteLine("return: " + obj);
return obj;
}
Console.WriteLine("return: null");
return null;
}
public static int? ForeachWithReturn(IEnumerable<int> enumerable)
{
Console.WriteLine("ForeachWithReturn:");
foreach (var obj in enumerable) {
Console.WriteLine("return: " + obj);
return obj;
}
Console.WriteLine("return: null");
return null;
}
}
}

3
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -510,7 +510,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -510,7 +510,6 @@ namespace ICSharpCode.Decompiler.CSharp
forStmt.Iterators.Add(iterator.Detach());
}
return forStmt;
default:
case LoopKind.While:
if (loop.Body == null) {
blockStatement = ConvertBlockContainer(container, true);
@ -534,6 +533,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -534,6 +533,8 @@ namespace ICSharpCode.Decompiler.CSharp
if (blockStatement.LastOrDefault() is ContinueStatement stmt)
stmt.Remove();
return new WhileStatement(conditionExpr, blockStatement);
default:
throw new ArgumentOutOfRangeException();
}
}

6
ICSharpCode.Decompiler/IL/DetectedLoop.cs

@ -23,7 +23,7 @@ using ICSharpCode.Decompiler.Util; @@ -23,7 +23,7 @@ using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL
{
public enum LoopKind { While, DoWhile, For }
public enum LoopKind { None, While, DoWhile, For }
public class DetectedLoop
{
@ -86,6 +86,10 @@ namespace ICSharpCode.Decompiler.IL @@ -86,6 +86,10 @@ namespace ICSharpCode.Decompiler.IL
private DetectedLoop DetectLoopInternal()
{
if (Container.EntryPoint.IncomingEdgeCount <= 1) {
Kind = LoopKind.None;
return this;
}
Kind = LoopKind.While;
ContinueJumpTarget = Container.EntryPoint;
if (Container.EntryPoint.Instructions.Count == 2

Loading…
Cancel
Save