Browse Source

Fix #1609: Decompilation of cached delegate-construction with unknown delegate type.

pull/1633/head
Siegfried Pammer 6 years ago
parent
commit
679623e4c3
  1. 2
      ICSharpCode.Decompiler/IL/Instructions.cs
  2. 2
      ICSharpCode.Decompiler/IL/Instructions.tt
  3. 2
      ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs
  4. 8
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

2
ICSharpCode.Decompiler/IL/Instructions.cs

@ -786,7 +786,7 @@ namespace ICSharpCode.Decompiler.IL @@ -786,7 +786,7 @@ namespace ICSharpCode.Decompiler.IL
clone.CloneVariables();
return clone;
}
public override StackType ResultType { get { return StackType.O; } }
public override StackType ResultType { get { return DelegateType?.GetStackType() ?? StackType.O; } }
public override void AcceptVisitor(ILVisitor visitor)
{
visitor.VisitILFunction(this);

2
ICSharpCode.Decompiler/IL/Instructions.tt

@ -51,7 +51,7 @@ @@ -51,7 +51,7 @@
CustomChildren(new [] {
new ChildInfo("body"),
new ChildInfo("localFunctions") { IsCollection = true, Type = "ILFunction" }
}), CustomConstructor, CustomWriteTo, CustomComputeFlags, CustomVariableName("function"), ResultType("O")
}), CustomConstructor, CustomWriteTo, CustomComputeFlags, CustomVariableName("function"), ResultType("DelegateType?.GetStackType() ?? StackType.O")
),
new OpCode("BlockContainer", "A container of IL blocks.",
ResultType("this.ExpectedResultType"), CustomConstructor, CustomVariableName("container"),

2
ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs

@ -68,7 +68,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -68,7 +68,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
if (!storeInst.MatchStsFld(out IField field2, out ILInstruction value) || !field.Equals(field2) || !field.IsCompilerGeneratedOrIsInCompilerGeneratedClass())
return false;
if (!DelegateConstruction.IsDelegateConstruction(value as NewObj, true))
if (!DelegateConstruction.IsDelegateConstruction(value.UnwrapConv(ConversionKind.Invalid) as NewObj, true))
return false;
var nextInstruction = inst.Parent.Children.ElementAtOrDefault(inst.ChildIndex + 1);
if (nextInstruction == null)

8
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -62,11 +62,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -62,11 +62,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
internal static bool IsDelegateConstruction(NewObj inst, bool allowTransformed = false)
{
if (inst == null || inst.Arguments.Count != 2 || inst.Method.DeclaringType.Kind != TypeKind.Delegate)
if (inst == null || inst.Arguments.Count != 2)
return false;
var opCode = inst.Arguments[1].OpCode;
return opCode == OpCode.LdFtn || opCode == OpCode.LdVirtFtn || (allowTransformed && opCode == OpCode.ILFunction);
if (!(opCode == OpCode.LdFtn || opCode == OpCode.LdVirtFtn || (allowTransformed && opCode == OpCode.ILFunction)))
return false;
var typeKind = inst.Method.DeclaringType.Kind;
return typeKind == TypeKind.Delegate || typeKind == TypeKind.Unknown;
}
static bool IsAnonymousMethod(ITypeDefinition decompiledTypeDefinition, IMethod method)

Loading…
Cancel
Save