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
ForWithMultipleVariables(); ForWithMultipleVariables();
DoubleForEachWithSameVariable(new[] { "a", "b", "c" }); DoubleForEachWithSameVariable(new[] { "a", "b", "c" });
ForeachExceptForNameCollision(new[] { 42, 43, 44, 45 }); 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() public static void ForWithMultipleVariables()
@ -90,5 +93,29 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
} }
Console.WriteLine("After finally!"); 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
forStmt.Iterators.Add(iterator.Detach()); forStmt.Iterators.Add(iterator.Detach());
} }
return forStmt; return forStmt;
default:
case LoopKind.While: case LoopKind.While:
if (loop.Body == null) { if (loop.Body == null) {
blockStatement = ConvertBlockContainer(container, true); blockStatement = ConvertBlockContainer(container, true);
@ -534,6 +533,8 @@ namespace ICSharpCode.Decompiler.CSharp
if (blockStatement.LastOrDefault() is ContinueStatement stmt) if (blockStatement.LastOrDefault() is ContinueStatement stmt)
stmt.Remove(); stmt.Remove();
return new WhileStatement(conditionExpr, blockStatement); return new WhileStatement(conditionExpr, blockStatement);
default:
throw new ArgumentOutOfRangeException();
} }
} }

6
ICSharpCode.Decompiler/IL/DetectedLoop.cs

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

Loading…
Cancel
Save