From 679623e4c32d9f00503f3c9e3400003bcdccd42a Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 4 Aug 2019 16:21:23 +0200 Subject: [PATCH] Fix #1609: Decompilation of cached delegate-construction with unknown delegate type. --- ICSharpCode.Decompiler/IL/Instructions.cs | 2 +- ICSharpCode.Decompiler/IL/Instructions.tt | 2 +- .../IL/Transforms/CachedDelegateInitialization.cs | 2 +- .../IL/Transforms/DelegateConstruction.cs | 8 +++++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs index 81190cd40..10136e36f 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions.cs @@ -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); diff --git a/ICSharpCode.Decompiler/IL/Instructions.tt b/ICSharpCode.Decompiler/IL/Instructions.tt index 18e6bd61e..9067456f0 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.tt +++ b/ICSharpCode.Decompiler/IL/Instructions.tt @@ -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"), diff --git a/ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs b/ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs index a0e365f92..38ba30608 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs @@ -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) diff --git a/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs b/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs index 7edfeb1ef..4d723a0b6 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs @@ -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)