Browse Source

Fix #2317: Crash in ExpressionBuilder.VisitStLoc when storing to a null pointer

pull/2566/head
Daniel Grunwald 4 years ago
parent
commit
47b12a1d9a
  1. 22
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 2
      ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

22
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -2712,26 +2712,32 @@ namespace ICSharpCode.Decompiler.CSharp
var pointer = Translate(inst.Target, typeHint: pointerTypeHint); var pointer = Translate(inst.Target, typeHint: pointerTypeHint);
TranslatedExpression target; TranslatedExpression target;
TranslatedExpression value = default; TranslatedExpression value = default;
// Cast pointer type if necessary: IType memoryType;
if (!TypeUtils.IsCompatiblePointerTypeForMemoryAccess(pointer.Type, inst.Type)) // Check if we need to cast to pointer type:
if (TypeUtils.IsCompatiblePointerTypeForMemoryAccess(pointer.Type, inst.Type))
{ {
// cast not necessary, we can use the existing type
memoryType = ((TypeWithElementType)pointer.Type).ElementType;
}
else
{
// We need to introduce a pointer cast
value = Translate(inst.Value, typeHint: inst.Type); value = Translate(inst.Value, typeHint: inst.Type);
IType castTargetType;
if (TypeUtils.IsCompatibleTypeForMemoryAccess(value.Type, inst.Type)) if (TypeUtils.IsCompatibleTypeForMemoryAccess(value.Type, inst.Type))
{ {
castTargetType = value.Type; memoryType = value.Type;
} }
else else
{ {
castTargetType = inst.Type; memoryType = inst.Type;
} }
if (pointer.Expression is DirectionExpression) if (pointer.Expression is DirectionExpression)
{ {
pointer = pointer.ConvertTo(new ByReferenceType(castTargetType), this); pointer = pointer.ConvertTo(new ByReferenceType(memoryType), this);
} }
else else
{ {
pointer = pointer.ConvertTo(new PointerType(castTargetType), this); pointer = pointer.ConvertTo(new PointerType(memoryType), this);
} }
} }
@ -2751,7 +2757,7 @@ namespace ICSharpCode.Decompiler.CSharp
{ {
target = new UnaryOperatorExpression(UnaryOperatorType.Dereference, pointer.Expression) target = new UnaryOperatorExpression(UnaryOperatorType.Dereference, pointer.Expression)
.WithoutILInstruction() .WithoutILInstruction()
.WithRR(new ResolveResult(((TypeWithElementType)pointer.Type).ElementType)); .WithRR(new ResolveResult(memoryType));
} }
} }
if (value.Expression == null) if (value.Expression == null)

2
ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

@ -544,7 +544,7 @@ namespace ICSharpCode.Decompiler.CSharp
} }
return new CastExpression(expressionBuilder.ConvertType(targetType), new NullReferenceExpression()) return new CastExpression(expressionBuilder.ConvertType(targetType), new NullReferenceExpression())
.WithILInstruction(this.ILInstructions) .WithILInstruction(this.ILInstructions)
.WithRR(new ConstantResolveResult(SpecialType.NullType, null)); .WithRR(new ConstantResolveResult(targetType, null));
} }
if (allowImplicitConversion) if (allowImplicitConversion)
{ {

Loading…
Cancel
Save