From d8a08822b728bbd708784804870ea6e89c5994bb Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 28 Dec 2019 22:49:31 +0100 Subject: [PATCH] Fix #1879: Incorrectly detected display class. --- .../Transforms/TransformDisplayClassUsage.cs | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs index aeca6f8e7..49e1c89cf 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs @@ -61,7 +61,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms foreach (var v in f.Variables.ToArray()) { if (context.Settings.YieldReturn && HandleMonoStateMachine(function, v, decompilationContext, f)) continue; - if ((context.Settings.AnonymousMethods || context.Settings.ExpressionTrees) && IsClosure(context, v, instructionsToRemove, out ITypeDefinition closureType, out var inst)) { + if ((context.Settings.AnonymousMethods || context.Settings.ExpressionTrees) && IsClosure(context, v, out ITypeDefinition closureType, out var inst)) { + if (!CanRemoveAllReferencesTo(context, v)) + continue; + instructionsToRemove.Add(inst); AddOrUpdateDisplayClass(f, v, closureType, inst, localFunctionClosureParameter: false); continue; } @@ -89,6 +92,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms } } + private bool CanRemoveAllReferencesTo(ILTransformContext context, ILVariable v) + { + foreach (var use in v.LoadInstructions) { + if (use.Parent.MatchStLoc(out var targetVar) && !IsClosure(context, targetVar, out _, out _)) { + return false; + } + } + return true; + } + private void AnalyzeUseSites(ILVariable v) { foreach (var use in v.LoadInstructions) { @@ -141,18 +154,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms } internal static bool IsClosure(ILTransformContext context, ILVariable variable, out ITypeDefinition closureType, out ILInstruction initializer) - { - return IsClosure(context, variable, instructionsToRemove: null, out closureType, out initializer); - } - - static bool IsClosure(ILTransformContext context, ILVariable variable, List instructionsToRemove, out ITypeDefinition closureType, out ILInstruction initializer) { closureType = null; initializer = null; if (variable.IsSingleDefinition && variable.StoreInstructions.SingleOrDefault() is StLoc inst) { initializer = inst; if (IsClosureInit(context, inst, out closureType)) { - instructionsToRemove?.Add(inst); return true; } }