From 98b99eddb83f690d23d975820670b3ae7ea7a7ec Mon Sep 17 00:00:00 2001
From: mohe2015 <mohe2015@users.noreply.github.com>
Date: Tue, 10 Oct 2017 13:33:33 +0200
Subject: [PATCH] Fix catch with object

---
 .../DetectCatchWhenConditionBlocks.cs         | 62 +++++++++++++------
 1 file changed, 44 insertions(+), 18 deletions(-)

diff --git a/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs b/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs
index 14bc7ac4e..49c579708 100644
--- a/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs
+++ b/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs
@@ -41,10 +41,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms
 					//   br whenConditionBlock
 					// }
 					var instructions = container.EntryPoint.Instructions;
-					((StLoc)instructions[0]).Value = exceptionSlot;
-					instructions[1].ReplaceWith(new Branch(whenConditionBlock));
-					instructions.RemoveAt(2);
-					container.SortBlocks(deleteUnreachableBlocks: true);
+					if (instructions.Count == 3) {
+						((StLoc)instructions[0]).Value = exceptionSlot;
+						instructions[1].ReplaceWith(new Branch(whenConditionBlock));
+						instructions.RemoveAt(2);
+						container.SortBlocks(deleteUnreachableBlocks: true);
+					} else if (instructions.Count == 2) {
+						// if (comp(isinst exceptionType(ldloc exceptionVar) != ldnull)) br whenConditionBlock
+						// br falseBlock
+						instructions[0].ReplaceWith(new Branch(whenConditionBlock));
+						instructions.RemoveAt(1);
+						container.SortBlocks(deleteUnreachableBlocks: true);
+					}
 				}
 			}
 		}
@@ -61,21 +69,39 @@ namespace ICSharpCode.Decompiler.IL.Transforms
 			exceptionType = null;
 			exceptionSlot = null;
 			whenConditionBlock = null;
-			if (entryPoint == null || entryPoint.IncomingEdgeCount != 1 || entryPoint.Instructions.Count != 3)
+			if (entryPoint == null || entryPoint.IncomingEdgeCount != 1)
 				return false;
-			if (!entryPoint.Instructions[0].MatchStLoc(out var temp, out var isinst) ||
-				temp.Kind != VariableKind.StackSlot || !isinst.MatchIsInst(out exceptionSlot, out exceptionType))
-				return false;
-			if (!exceptionSlot.MatchLdLoc(out var exceptionVar) || exceptionVar.Kind != VariableKind.Exception)
-				return false;
-			if (!entryPoint.Instructions[1].MatchIfInstruction(out var condition, out var branch))
-				return false;
-			if (!condition.MatchCompNotEquals(out var left, out var right))
-				return false;
-			if (!entryPoint.Instructions[2].MatchBranch(out var falseBlock) || !MatchFalseBlock(container, falseBlock, out var returnVar, out var exitBlock))
-				return false;
-			if ((left.MatchLdNull() && right.MatchLdLoc(temp)) || (right.MatchLdNull() && left.MatchLdLoc(temp))) {
-				return branch.MatchBranch(out whenConditionBlock);
+			if (entryPoint.Instructions.Count == 3) {
+				if (!entryPoint.Instructions[0].MatchStLoc(out var temp, out var isinst) ||
+					temp.Kind != VariableKind.StackSlot || !isinst.MatchIsInst(out exceptionSlot, out exceptionType))
+					return false;
+				if (!exceptionSlot.MatchLdLoc(out var exceptionVar) || exceptionVar.Kind != VariableKind.Exception)
+					return false;
+				if (!entryPoint.Instructions[1].MatchIfInstruction(out var condition, out var branch))
+					return false;
+				if (!condition.MatchCompNotEquals(out var left, out var right))
+					return false;
+				if (!entryPoint.Instructions[2].MatchBranch(out var falseBlock) || !MatchFalseBlock(container, falseBlock, out var returnVar, out var exitBlock))
+					return false;
+				if ((left.MatchLdNull() && right.MatchLdLoc(temp)) || (right.MatchLdNull() && left.MatchLdLoc(temp))) {
+					return branch.MatchBranch(out whenConditionBlock);
+				}
+			} else if (entryPoint.Instructions.Count == 2) {
+				// if (comp(isinst exceptionType(ldloc exceptionVar) != ldnull)) br whenConditionBlock
+				// br falseBlock
+				if (!entryPoint.Instructions[0].MatchIfInstruction(out var condition, out var branch))
+					return false;
+				if (!condition.MatchCompNotEquals(out var left, out var right))
+					return false;
+				if (!entryPoint.Instructions[1].MatchBranch(out var falseBlock) || !MatchFalseBlock(container, falseBlock, out var returnVar, out var exitBlock))
+					return false;
+				if (!left.MatchIsInst(out exceptionSlot, out exceptionType))
+					return false;
+				if (!exceptionSlot.MatchLdLoc(out var exceptionVar) || exceptionVar.Kind != VariableKind.Exception)
+					return false;
+				if (right.MatchLdNull()) {
+					return branch.MatchBranch(out whenConditionBlock);
+				}
 			}
 			return false;
 		}