From 97efc7b7f5807c47c0316bd7ec51ebb661c4a4a4 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 11 Jan 2018 19:56:59 +0100 Subject: [PATCH] Fix some value type stack slots incorrectly being decompiled to a variable of type "object". --- .../CSharp/ExpressionBuilder.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index c7c8b373a..035859733 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -436,12 +436,23 @@ namespace ICSharpCode.Decompiler.CSharp protected internal override TranslatedExpression VisitStLoc(StLoc inst, TranslationContext context) { var translatedValue = Translate(inst.Value, typeHint: inst.Variable.Type); - if (inst.Variable.Kind == VariableKind.StackSlot && inst.Variable.IsSingleDefinition - && inst.Variable.StackType == translatedValue.Type.GetStackType() - && translatedValue.Type.Kind != TypeKind.Null && !loadedVariablesSet.Contains(inst.Variable)) { - inst.Variable.Type = translatedValue.Type; + if (inst.Variable.Kind == VariableKind.StackSlot && !loadedVariablesSet.Contains(inst.Variable)) { + // Stack slots in the ILAst have inaccurate types (e.g. System.Object for StackType.O) + // so we should replace them with more accurate types where possible: + if ((inst.Variable.IsSingleDefinition || IsOtherValueType(translatedValue.Type)) + && inst.Variable.StackType == translatedValue.Type.GetStackType() + && translatedValue.Type.Kind != TypeKind.Null) { + inst.Variable.Type = translatedValue.Type; + } else if (inst.Value.MatchDefaultValue(out var type) && IsOtherValueType(type)) { + inst.Variable.Type = type; + } } return Assignment(ConvertVariable(inst.Variable).WithoutILInstruction(), translatedValue).WithILInstruction(inst); + + bool IsOtherValueType(IType type) + { + return type.IsReferenceType == false && type.GetStackType() == StackType.O; + } } protected internal override TranslatedExpression VisitComp(Comp inst, TranslationContext context)