Browse Source

Fix some value type stack slots incorrectly being decompiled to a variable of type "object".

pull/1033/merge
Daniel Grunwald 8 years ago
parent
commit
97efc7b7f5
  1. 15
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

15
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -436,12 +436,23 @@ namespace ICSharpCode.Decompiler.CSharp @@ -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
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 && !loadedVariablesSet.Contains(inst.Variable)) {
&& 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)

Loading…
Cancel
Save