Browse Source

Add delayed type inference step for stack slots (in RemoveDeadVariableInit).

pull/1129/head
Siegfried Pammer 7 years ago
parent
commit
110d4592a6
  1. 23
      ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs

23
ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Decompiler.FlowAnalysis;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.IL.Transforms
{
@ -27,6 +28,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -27,6 +28,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// (=the initial value is a dead store).
///
/// In yield return generators, additionally removes dead 'V = null;' assignments.
///
/// Additionally infers IType of stack slots that have StackType.Ref
/// </summary>
public class RemoveDeadVariableInit : IILTransform
{
@ -66,6 +69,26 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -66,6 +69,26 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
}
// Try to infer IType of stack slots that are of StackType.Ref:
foreach (var v in function.Variables) {
if (v.Kind == VariableKind.StackSlot && v.StackType == StackType.Ref && v.AddressCount == 0) {
IType newType = null;
// Multiple store are possible in case of (c ? ref a : ref b) += 1, for example.
foreach (var stloc in v.StoreInstructions.OfType<StLoc>()) {
var inferredType = stloc.Value.InferType();
// cancel, if types of values do not match exactly
if (newType != null && !newType.Equals(inferredType)) {
newType = SpecialType.UnknownType;
break;
}
newType = inferredType;
}
// Only overwrite existing type, if a "better" type was found.
if (newType != null && newType != SpecialType.UnknownType)
v.Type = newType;
}
}
}
}
}

Loading…
Cancel
Save