From 3e6e628483f9438ce51e8043587aa59ca8f130d1 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 8 Aug 2020 15:01:12 +0200 Subject: [PATCH] Fix missing conversion on ref-reassignment. --- .../TestCases/ILPretty/Unsafe.cs | 10 +++++++ .../TestCases/ILPretty/Unsafe.il | 26 +++++++++++++++++++ .../CSharp/ExpressionBuilder.cs | 1 + 3 files changed, 37 insertions(+) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.cs index 8d45ab794..be41f47b0 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.cs @@ -26,6 +26,16 @@ internal sealed class ExtraUnsafeTests return (uint*)Unsafe.AsPointer(ref managedPtr); } + public static ref ulong RefAssignTypeMismatch(ref uint a, ref uint b) + { + ref ushort reference = ref Unsafe.As(ref a); + if (a != 0) { + reference = ref Unsafe.As(ref b); + } + Console.WriteLine(reference); + return ref Unsafe.As(ref reference); + } + public unsafe static byte[] Issue1292(int val, byte[] arr) { //The blocks IL_0019 are reachable both inside and outside the pinned region starting at IL_0013. ILSpy has duplicated these blocks in order to place them both within and outside the `fixed` statement. diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.il index 2c6605531..7766f0c80 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.il @@ -475,6 +475,32 @@ ret } + .method public hidebysig static uint64& RefAssignTypeMismatch(uint32& a, uint32& b) + { + .maxstack 8 + .locals ( + [0] uint16& + ) + + ldarg.0 + stloc.0 + + ldarg.0 + ldind.i4 + brfalse lbl + + ldarg.1 + stloc.0 + +lbl: + ldloc.0 + ldind.i2 + call void [mscorlib]System.Console::WriteLine(uint16) + + ldloc.0 + ret + } + .method public hidebysig static uint8[] Issue1292 ( int32 val, diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 7bbd4f964..09bbb7c19 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -640,6 +640,7 @@ namespace ICSharpCode.Decompiler.CSharp if (lhs.Expression is DirectionExpression dirExpr && lhs.ResolveResult is ByReferenceResolveResult lhsRefRR) { // ref (re-)assignment, emit "ref (a = ref b)". lhs = lhs.UnwrapChild(dirExpr.Expression); + translatedValue = translatedValue.ConvertTo(lhsRefRR.Type, this, allowImplicitConversion: true); var assign = new AssignmentExpression(lhs.Expression, translatedValue.Expression) .WithRR(new OperatorResolveResult(lhs.Type, ExpressionType.Assign, lhsRefRR, translatedValue.ResolveResult)); return new DirectionExpression(FieldDirection.Ref, assign)