From aa9f2e779738570b4a864ca4b75d3d51622ed5a2 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 24 Feb 2018 19:57:18 +0100 Subject: [PATCH] Fix interaction of using-transform with ?. operator. --- .../IL/Transforms/UsingTransform.cs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs index c16bb2f0b..56b54d17b 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs @@ -199,26 +199,32 @@ namespace ICSharpCode.Decompiler.IL.Transforms numObjVarLoadsInCheck = 2; CallVirt callVirt; if (objVar.Type.IsKnownType(KnownTypeCode.NullableOfT)) { - if (!checkInst.MatchIfInstruction(out var condition, out var disposeInst)) - return false; - if (!NullableLiftingTransform.MatchHasValueCall(condition, objVar)) - return false; - if (!(disposeInst is Block disposeBlock) || disposeBlock.Instructions.Count != 1) + if (checkInst.MatchIfInstruction(out var condition, out var disposeInst)) { + if (!NullableLiftingTransform.MatchHasValueCall(condition, objVar)) + return false; + if (!(disposeInst is Block disposeBlock) || disposeBlock.Instructions.Count != 1) + return false; + callVirt = disposeBlock.Instructions[0] as CallVirt; + } else if (checkInst.MatchNullableRewrap(out disposeInst)) { + callVirt = disposeInst as CallVirt; + } else { return false; - if (!(disposeBlock.Instructions[0] is CallVirt cv)) + } + if (callVirt == null) return false; - callVirt = cv; if (callVirt.Method.FullName != "System.IDisposable.Dispose") return false; if (callVirt.Method.Parameters.Count > 0) return false; if (callVirt.Arguments.Count != 1) return false; - var firstArg = cv.Arguments.FirstOrDefault(); + var firstArg = callVirt.Arguments.FirstOrDefault(); if (!(firstArg.MatchUnboxAny(out var innerArg1, out var unboxType) && unboxType.IsKnownType(KnownTypeCode.IDisposable))) { if (!firstArg.MatchAddressOf(out var innerArg2)) return false; - return NullableLiftingTransform.MatchGetValueOrDefault(innerArg2, objVar); + return NullableLiftingTransform.MatchGetValueOrDefault(innerArg2, objVar) + || (innerArg2 is NullableUnwrap unwrap + && unwrap.Argument.MatchLdLoc(objVar)); } else { if (!(innerArg1.MatchBox(out firstArg, out var boxType) && boxType.IsKnownType(KnownTypeCode.NullableOfT) && NullableType.GetUnderlyingType(boxType).Equals(NullableType.GetUnderlyingType(objVar.Type))))