diff --git a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs index 9adeba7d3..6a8a7a1cc 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs @@ -419,6 +419,12 @@ namespace ICSharpCode.Decompiler.Ast.Transforms // We just care that we can move it in front of the loop: if (declarationPoint != loop) return null; + + // Make sure that the enumerator variable is not used inside the body + foreach (Statement stmt in m.Get("statement")) { + if (UsesEnumerator(stmt, enumeratorVar.Name)) + return null; + } BlockStatement newBody = new BlockStatement(); foreach (Statement stmt in m.Get("variablesInsideLoop")) @@ -1160,5 +1166,40 @@ namespace ICSharpCode.Decompiler.Ast.Transforms return null; } #endregion + + #region UsesEnumerator helper + class UsesEnumeratorVisitor : DepthFirstAstVisitor + { + Identifier enumeratorIdentifier; + + public UsesEnumeratorVisitor(string identifier) + { + enumeratorIdentifier = Identifier.Create(identifier); + } + + protected override bool VisitChildren(AstNode node) + { + AstNode next; + for (var child = node.FirstChild; child != null; child = next) { + // Store next to allow the loop to continue + // if the visitor removes/replaces child. + next = child.NextSibling; + if (child.AcceptVisitor(this)) + return true; + } + return false; + } + + public override bool VisitIdentifier(Identifier identifier) + { + return identifier.IsMatch(enumeratorIdentifier); + } + } + + bool UsesEnumerator(Statement statement, string enumeratorVarName) + { + return statement.AcceptVisitor(new UsesEnumeratorVisitor(enumeratorVarName)); + } + #endregion } }