diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/DeconstructionTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/DeconstructionTests.cs index ea180592a..626052b95 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/DeconstructionTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/DeconstructionTests.cs @@ -134,6 +134,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness NoDeconstruction_NotUsingConver_Tuple(); NullReferenceException_Field_Deconstruction(out _); NullReferenceException_RefLocalReferencesField_Deconstruction(out _); + NullReferenceException_RefLocalReferencesArrayElement_Deconstruction(out _, null); } public void Property_NoDeconstruction_SwappedAssignments() @@ -211,5 +212,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness Console.WriteLine(ex.GetType().FullName); } } + + public void NullReferenceException_RefLocalReferencesArrayElement_Deconstruction(out int a, int[] arr) + { + try { + ref int i = ref arr[0]; + (i, a) = GetSource(); + } catch (Exception ex) { + a = 0; + Console.WriteLine(ex.GetType().FullName); + } + } } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs index 2d9146596..ceee27d5e 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs @@ -231,5 +231,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { (a, GetRef()) = GetSource(); } + + //public void ArrayAssign_FloatToDoubleConversion(double[] arr) + //{ + // (arr[0], arr[1], arr[2]) = GetSource(); + //} + + public void Field_NoConversion() + { + (Get(0).IntField, Get(1).IntField) = GetSource(); + } } } diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 840df99ab..b18e57518 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -3440,7 +3440,10 @@ namespace ICSharpCode.Decompiler.CSharp Debug.Assert(call.Arguments.Last().MatchLdLoc(value)); break; case StObj stobj: - ReplaceAssignmentTarget(stobj.Target); + var target = stobj.Target; + while (target.MatchLdFlda(out var nestedTarget, out _)) + target = nestedTarget; + ReplaceAssignmentTarget(target); Debug.Assert(stobj.Value.MatchLdLoc(value)); break; default: diff --git a/ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs index 9c3145f57..62ba9aae1 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs @@ -230,13 +230,15 @@ namespace ICSharpCode.Decompiler.IL return true; case StObj stobj: var target = stobj.Target; + while (target.MatchLdFlda(out var nestedTarget, out _)) + target = nestedTarget; if (target.Flags == InstructionFlags.None) { // OK - we accept integer literals, etc. } else if (target.MatchLdLoc(out var v)) { } else { return false; } - if (target.InferType(typeSystem) is ByReferenceType brt) + if (stobj.Target.InferType(typeSystem) is ByReferenceType brt) expectedType = brt.ElementType; else expectedType = SpecialType.UnknownType;