Browse Source

Fix bug in for-loop detection: Could not detect for-loops when the condition used multiple variables.

pull/892/merge
Siegfried Pammer 8 years ago
parent
commit
f488201762
  1. 26
      ICSharpCode.Decompiler/IL/DetectedLoop.cs

26
ICSharpCode.Decompiler/IL/DetectedLoop.cs

@ -116,10 +116,10 @@ namespace ICSharpCode.Decompiler.IL
AdditionalBlocks = Container.Blocks.Skip(1).Where(b => b != IncrementBlock).ToArray(); AdditionalBlocks = Container.Blocks.Skip(1).Where(b => b != IncrementBlock).ToArray();
return this; return this;
} else if (trueInst is Block block) { } else if (trueInst is Block block) {
var variable = GetVariableFromCondition(conditionInst);
var last = block.Instructions.LastOrDefault(); var last = block.Instructions.LastOrDefault();
var secondToLast = block.Instructions.SecondToLastOrDefault(); var secondToLast = block.Instructions.SecondToLastOrDefault();
if (variable != null && last != null && secondToLast != null && last.MatchBranch(Container.EntryPoint) && MatchIncrement(secondToLast, variable)) { if (last != null && secondToLast != null && last.MatchBranch(Container.EntryPoint) &&
MatchIncrement(secondToLast, out var variable) && conditionInst.Children.Any(c => c.MatchLdLoc(variable))) {
Kind = LoopKind.For; Kind = LoopKind.For;
IncrementTarget = variable; IncrementTarget = variable;
AdditionalBlocks = Container.Blocks.Skip(1).ToArray(); AdditionalBlocks = Container.Blocks.Skip(1).ToArray();
@ -144,22 +144,16 @@ namespace ICSharpCode.Decompiler.IL
return this; return this;
} }
static ILVariable GetVariableFromCondition(ILInstruction conditionInst) static bool MatchIncrement(ILInstruction inst, out ILVariable variable)
{ {
var ldLocs = conditionInst.Children.OfType<LdLoc>().ToArray(); if (!inst.MatchStLoc(out variable, out var value))
if (ldLocs.Length == 1)
return ldLocs[0].Variable;
else
return null;
}
static bool MatchIncrement(ILInstruction inst, ILVariable variable)
{
if (!inst.MatchStLoc(variable, out var value))
return false; return false;
if (!value.MatchBinaryNumericInstruction(BinaryNumericOperator.Add, out var left, out var right)) if (!value.MatchBinaryNumericInstruction(BinaryNumericOperator.Add, out var left, out var right)) {
return false; if (value is CompoundAssignmentInstruction cai) {
return left.MatchLdLoc(variable) && right.MatchLdcI(out var val) && val == 1; left = cai.Target;
} else return false;
}
return left.MatchLdLoc(variable);
} }
} }
} }

Loading…
Cancel
Save