From 7ad556e0bf720d93a8fb2e313596c04d659c0e37 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 11 Dec 2017 00:42:29 +0100 Subject: [PATCH] Do not detect array initializer if element type and store type do not match. --- .../Transforms/TransformArrayInitializers.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs index e6884d395..88a4c9d3d 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs @@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms } if (arrayLength.Length == 1) { int instructionsToRemove; - if (HandleSimpleArrayInitializer(body, pos + 1, v, arrayLength[0], out values, out instructionsToRemove)) { + if (HandleSimpleArrayInitializer(body, pos + 1, v, elementType, arrayLength[0], out values, out instructionsToRemove)) { context.Step("HandleSimpleArrayInitializer", inst); var block = new Block(BlockKind.ArrayInitializer); var tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type); @@ -85,7 +85,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms ILInlining.InlineIfPossible(body, pos, context); return true; } - if (HandleJaggedArrayInitializer(body, pos + 1, v, arrayLength[0], out ILVariable finalStore, out values, out instructionsToRemove)) { + if (HandleJaggedArrayInitializer(body, pos + 1, v, elementType, arrayLength[0], out ILVariable finalStore, out values, out instructionsToRemove)) { context.Step("HandleJaggedArrayInitializer", inst); var block = new Block(BlockKind.ArrayInitializer); var tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type); @@ -163,7 +163,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms /// /// Handle simple case where RuntimeHelpers.InitializeArray is not used. /// - bool HandleSimpleArrayInitializer(Block block, int pos, ILVariable store, int length, out ILInstruction[] values, out int instructionsToRemove) + bool HandleSimpleArrayInitializer(Block block, int pos, ILVariable store, IType elementType, int length, out ILInstruction[] values, out int instructionsToRemove) { instructionsToRemove = 0; values = null; @@ -171,12 +171,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms int index = 0; int elementCount = 0; for (int i = pos; i < block.Instructions.Count; i++) { - ILInstruction target, value; - IType type; if (index >= length) break; - if (!block.Instructions[i].MatchStObj(out target, out value, out type) || value.Descendants.OfType().Any(inst => inst.Variable == store)) + if (!block.Instructions[i].MatchStObj(out ILInstruction target, out ILInstruction value, out IType type) || value.Descendants.OfType().Any(inst => inst.Variable == store)) break; + if (!type.Equals(elementType)) + return false; var ldelem = target as LdElema; if (ldelem == null || !ldelem.Array.MatchLdLoc(store) || ldelem.Indices.Count != 1 || !ldelem.Indices[0].MatchLdcI4(out index)) break; @@ -190,22 +190,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms return elementCount > 0; } - bool HandleJaggedArrayInitializer(Block block, int pos, ILVariable store, int length, out ILVariable finalStore, out ILInstruction[] values, out int instructionsToRemove) + bool HandleJaggedArrayInitializer(Block block, int pos, ILVariable store, IType elementType, int length, out ILVariable finalStore, out ILInstruction[] values, out int instructionsToRemove) { instructionsToRemove = 0; finalStore = null; values = new ILInstruction[length]; + ILInstruction initializer; + IType type; for (int i = 0; i < length; i++) { - ILVariable temp; - ILInstruction storeLoad; // 1. Instruction: (optional) temporary copy of store - bool hasTemporaryCopy = block.Instructions[pos].MatchStLoc(out temp, out storeLoad) && storeLoad.MatchLdLoc(store); + bool hasTemporaryCopy = block.Instructions[pos].MatchStLoc(out ILVariable temp, out ILInstruction storeLoad) && storeLoad.MatchLdLoc(store); if (hasTemporaryCopy) { - if (!MatchJaggedArrayStore(block, pos + 1, temp, i, out initializer)) + if (!MatchJaggedArrayStore(block, pos + 1, temp, i, out initializer, out type) || !elementType.Equals(type)) return false; } else { - if (!MatchJaggedArrayStore(block, pos, store, i, out initializer)) + if (!MatchJaggedArrayStore(block, pos, store, i, out initializer, out type) || !elementType.Equals(type)) return false; } values[i] = initializer; @@ -224,13 +224,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms return true; } - bool MatchJaggedArrayStore(Block block, int pos, ILVariable store, int index, out ILInstruction initializer) + bool MatchJaggedArrayStore(Block block, int pos, ILVariable store, int index, out ILInstruction initializer, out IType type) { initializer = null; + type = null; // 3. Instruction: stobj(ldelema(ldloc temp, ldc.i4 0), ldloc tempArrayLoad) var finalInstruction = block.Instructions.ElementAtOrDefault(pos + 1); ILInstruction tempAccess, tempArrayLoad; - IType type; ILVariable initializerStore; if (finalInstruction == null || !finalInstruction.MatchStObj(out tempAccess, out tempArrayLoad, out type) || !tempArrayLoad.MatchLdLoc(out initializerStore)) return false;