Browse Source

Don't match sub.ovf in SwitchAnalysis.

pull/1296/head
Daniel Grunwald 7 years ago
parent
commit
f4613de2ba
  1. 24
      ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs
  2. 31
      ICSharpCode.Decompiler/Util/CollectionExtensions.cs
  3. 3
      ICSharpCode.Decompiler/Util/LongSet.cs

24
ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs

@ -233,21 +233,17 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -233,21 +233,17 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
bool MatchSwitchVar(ILInstruction inst, out long sub)
{
if (inst.MatchBinaryNumericInstruction(BinaryNumericOperator.Sub, out var left, out var right) && right.MatchLdcI(out sub))
return MatchSwitchVar(left);
if (inst is BinaryNumericInstruction bn
&& bn.Operator == BinaryNumericOperator.Sub
&& !bn.CheckForOverflow && !bn.IsLifted
&& bn.Right.MatchLdcI(out sub))
{
return MatchSwitchVar(bn.Left);
}
sub = 0;
return MatchSwitchVar(inst);
}
/// <summary>
/// Shifts a LongInterval, treating long.MinValue and long.MaxValue like float.Positive/NegativeInfinity
/// </summary>
LongInterval ShiftInterval(LongInterval interval, long offset)
{
return new LongInterval(
interval.Start == long.MinValue ? long.MinValue : interval.Start + offset,
interval.End == long.MinValue ? long.MinValue : interval.End + offset);
}
/// <summary>
/// Analyzes the boolean condition, returning the set of values of the interesting
@ -256,11 +252,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -256,11 +252,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
private bool AnalyzeCondition(ILInstruction condition, out LongSet trueValues)
{
if (condition is Comp comp && MatchSwitchVar(comp.Left, out var sub) && comp.Right.MatchLdcI(out long val)) {
// if (comp(V OP val))
// if (comp((V - sub) OP val))
trueValues = MakeSetWhereComparisonIsTrue(comp.Kind, val, comp.Sign);
if (sub != 0)
trueValues = new LongSet(trueValues.Intervals.Select(i => ShiftInterval(i, sub)));
trueValues = trueValues.AddOffset(sub);
return true;
} else if (MatchSwitchVar(condition)) {
// if (ldloc V) --> branch for all values except 0

31
ICSharpCode.Decompiler/Util/CollectionExtensions.cs

@ -200,27 +200,28 @@ namespace ICSharpCode.Decompiler.Util @@ -200,27 +200,28 @@ namespace ICSharpCode.Decompiler.Util
/// </summary>
public static IEnumerable<T> Merge<T>(this IEnumerable<T> input1, IEnumerable<T> input2, Comparison<T> comparison)
{
var enumA = input1.GetEnumerator();
var enumB = input2.GetEnumerator();
bool moreA = enumA.MoveNext();
bool moreB = enumB.MoveNext();
while (moreA && moreB) {
if (comparison(enumA.Current, enumB.Current) <= 0) {
using (var enumA = input1.GetEnumerator())
using (var enumB = input2.GetEnumerator()) {
bool moreA = enumA.MoveNext();
bool moreB = enumB.MoveNext();
while (moreA && moreB) {
if (comparison(enumA.Current, enumB.Current) <= 0) {
yield return enumA.Current;
moreA = enumA.MoveNext();
} else {
yield return enumB.Current;
moreB = enumB.MoveNext();
}
}
while (moreA) {
yield return enumA.Current;
moreA = enumA.MoveNext();
} else {
}
while (moreB) {
yield return enumB.Current;
moreB = enumB.MoveNext();
}
}
while (moreA) {
yield return enumA.Current;
moreA = enumA.MoveNext();
}
while (moreB) {
yield return enumB.Current;
moreB = enumB.MoveNext();
}
}
/// <summary>

3
ICSharpCode.Decompiler/Util/LongSet.cs

@ -203,6 +203,9 @@ namespace ICSharpCode.Decompiler.Util @@ -203,6 +203,9 @@ namespace ICSharpCode.Decompiler.Util
/// </summary>
public LongSet AddOffset(long val)
{
if (val == 0) {
return this;
}
var newIntervals = new List<LongInterval>(Intervals.Length + 1);
foreach (var element in Intervals) {
long newStart = unchecked(element.Start + val);

Loading…
Cancel
Save