From d65b109fbcc311043f4c3183d86bc1a615843cc6 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Mon, 30 Sep 2019 21:48:16 +0200 Subject: [PATCH] Fix #1689: Add support for null propagation on array access: `arr?[i]` --- .../TestCases/Pretty/NullPropagation.cs | 8 +++++++- .../IL/Transforms/NullPropagationTransform.cs | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs index 5886234e18..6d21918332 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs @@ -184,7 +184,7 @@ public void CoalescingString() { Use(GetMyClass()?.Text ?? "Hello"); } - + public void CallOnValueTypeField() { Use(GetMyClass()?.IntVal.ToString()); @@ -265,6 +265,12 @@ private void Setter(MyClass c) return (obj as ICollection)?.Count + (obj as ICollection)?.Count; } + private static void Issue1689(List setsOfNumbers) + { + Console.WriteLine(setsOfNumbers?[0]?[1].ToString() == "2"); + Console.WriteLine(setsOfNumbers?[1]?[1].ToString() == null); + } + private static dynamic DynamicNullProp(dynamic a) { return a?.b.c(1)?.d[10]; diff --git a/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs index a30ebcab97..b8da2c416e 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs @@ -18,6 +18,7 @@ using System; using System.Diagnostics; +using System.Linq; using ICSharpCode.Decompiler.TypeSystem; namespace ICSharpCode.Decompiler.IL.Transforms @@ -211,6 +212,11 @@ bool IsValidAccessChain(ILVariable testedVar, Mode mode, ILInstruction inst, out return false; } else if (inst is LdLen ldLen) { inst = ldLen.Array; + } else if (inst is LdElema ldElema) { + inst = ldElema.Array; + // ensure the access chain does not contain any 'nullable.unwrap' that aren't directly part of the chain + if (ldElema.Indices.Any(i => i.HasFlag(InstructionFlags.MayUnwrapNull))) + return false; } else if (inst is NullableUnwrap unwrap) { inst = unwrap.Argument; if (unwrap.RefInput && inst is AddressOf addressOf) {