From 8563d1b747f36419a3bb16730cfeca68ca36087b Mon Sep 17 00:00:00 2001 From: upstream Date: Fri, 11 Sep 2026 23:55:33 +0200 Subject: [PATCH] Upstream icsharpcode/ILSpy state of the touched files before 3d1d1be13b --- .../ILPrettyTestRunner.cs | 6 - .../TestCases/ILPretty/Issue3659.cs | 65 ----------- .../TestCases/ILPretty/Issue3659.il | 109 ------------------ .../DetectCatchWhenConditionBlocks.cs | 68 ----------- 4 files changed, 248 deletions(-) delete mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3659.cs delete mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3659.il diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs index ab22441..44d08a2 100644 --- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs @@ -267,12 +267,6 @@ namespace ICSharpCode.Decompiler.Tests await Run(); } - [Test] - public async Task Issue3659() - { - await Run(); - } - [Test] public async Task Issue3466() { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3659.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3659.cs deleted file mode 100644 index b9405a3..0000000 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3659.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using Microsoft.VisualBasic.CompilerServices; - -namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty -{ - public class Issue3659 - { - public static void Func(ref Issue3659 obj, object value) - { - } - - public static int ShowMessage(string a, int b, string c, object d, int e) - { - return 0; - } - - internal void VBFunction(object value) - { - int try0000_dispatch = -1; - int num2 = default; - int num = default; - while (true) - { - try - { - /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; - switch (try0000_dispatch) - { - default: - { - ProjectData.ClearProjectError(); - num2 = 2; - Issue3659 obj = this; - Func(ref obj, value); - goto end_IL_0000; - } - case 40: - num = -1; - switch (num2) - { - case 2: - ShowMessage("VBFunction", 0, "Exception", null, 0); - goto end_IL_0000; - } - break; - } - } - catch (Exception ex) when ((num2 != 0) & (num == 0)) - { - ProjectData.SetProjectError(ex); - try0000_dispatch = 40; - continue; - } - throw ProjectData.CreateProjectError(-214628237); - continue; - end_IL_0000: - break; - } - if (num != 0) - { - ProjectData.ClearProjectError(); - } - } - } -} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3659.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3659.il deleted file mode 100644 index f17e053..0000000 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3659.il +++ /dev/null @@ -1,109 +0,0 @@ -.assembly extern System.Runtime -{ - .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) - .ver 4:0:0:0 -} -.assembly extern Microsoft.VisualBasic.Core -{ - .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) - .ver 10:0:0:0 -} -.assembly Issue3659 { .ver 0:0:0:0 } -.module Issue3659.dll - -.class private auto ansi '' -{ -} - -.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3659 - extends [System.Runtime]System.Object -{ - .method public hidebysig static void Func(class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3659& obj, object 'value') cil managed - { - ret - } - - .method public hidebysig static int32 ShowMessage(string a, int32 b, string c, object d, int32 e) cil managed - { - ldc.i4.0 - ret - } - - .method assembly hidebysig instance void VBFunction(object 'value') cil managed - { - .maxstack 5 - .locals init ( - [0] int32, - [1] int32, - [2] class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3659 - ) - - .try - { - IL_0000: call void [Microsoft.VisualBasic.Core]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError() - IL_0005: ldc.i4.2 - IL_0006: stloc.0 - IL_0007: ldarg.0 - IL_0008: stloc.2 - IL_0009: ldloca.s 2 - IL_000b: ldarg.1 - IL_000c: call void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3659::Func(class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3659&, object) - IL_0011: br.s IL_0026 - - IL_0013: ldstr "VBFunction" - IL_0018: ldc.i4.0 - IL_0019: ldstr "Exception" - IL_001e: ldnull - IL_001f: ldc.i4.0 - IL_0020: call int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3659::ShowMessage(string, int32, string, object, int32) - IL_0025: pop - - IL_0026: leave.s IL_0069 - - IL_0028: ldc.i4.m1 - IL_0029: stloc.1 - IL_002a: ldloc.0 - IL_002b: switch (IL_003c, IL_003c, IL_0013) - - IL_003c: leave.s IL_005e - } - filter - { - IL_003e: isinst [System.Runtime]System.Exception - IL_0043: ldnull - IL_0044: cgt.un - IL_0046: ldloc.0 - IL_0047: ldc.i4.0 - IL_0048: cgt.un - IL_004a: and - IL_004b: ldloc.1 - IL_004c: ldc.i4.0 - IL_004d: ceq - IL_004f: and - IL_0050: endfilter - } - { - IL_0052: castclass [System.Runtime]System.Exception - IL_0057: call void [Microsoft.VisualBasic.Core]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [System.Runtime]System.Exception) - IL_005c: leave.s IL_0028 - } - - IL_005e: ldc.i4 -214628237 - IL_0063: call class [System.Runtime]System.Exception [Microsoft.VisualBasic.Core]Microsoft.VisualBasic.CompilerServices.ProjectData::CreateProjectError(int32) - IL_0068: throw - - IL_0069: ldloc.1 - IL_006a: brfalse.s IL_0071 - - IL_006c: call void [Microsoft.VisualBasic.Core]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError() - - IL_0071: ret - } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - ldarg.0 - call instance void [System.Runtime]System.Object::.ctor() - ret - } -} diff --git a/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs b/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs index 2cc1ba5..5aa9064 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs @@ -69,79 +69,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms container.SortBlocks(deleteUnreachableBlocks: true); } - PropagateExceptionVariable(context, catchBlock); - } - else if (catchBlock.Filter is BlockContainer filterContainer - && MatchTypeTestConjunction(catchBlock.Variable, filterContainer, - out var conjunctionType, out var typeTest) - && conjunctionType.GetStackType() == catchBlock.Variable.StackType) - { - context.Step($"Detected catch-when type test for {catchBlock.Variable.Name}", typeTest); - catchBlock.Variable.Type = conjunctionType; - var remainder = typeTest.Right; - typeTest.ReplaceWith(remainder); - context.EndStep(remainder); - PropagateExceptionVariable(context, catchBlock); } } } - /// - /// BlockContainer { - /// Block entryPoint (incoming: 1) { - /// leave container(bit.and(bit.and(comp(isinst T(ldloc exceptionVar) != ldnull), cond1), cond2)) - /// } - /// } - /// The Visual Basic compiler emits the whole filter as one non-short-circuiting - /// expression rather than the block chain csc emits, so the type test sits in a - /// conjunction instead of a branch. On a match, typeTest is the innermost `bit.and`, - /// whose right operand is the filter that remains once the test moves to the catch type. - /// - bool MatchTypeTestConjunction(ILVariable exceptionVar, BlockContainer container, - out IType exceptionType, out BinaryNumericInstruction typeTest) - { - exceptionType = null; - typeTest = null; - var entryPoint = container.EntryPoint; - if (entryPoint == null || entryPoint.IncomingEdgeCount != 1 || entryPoint.Instructions.Count != 1) - return false; - if (!entryPoint.Instructions[0].MatchLeave(container, out var condition)) - return false; - // Once the test moves to the catch type, the other conjuncts stop running for a - // non-matching exception, which is only invisible if they have no side effects. - if (!SemanticHelper.IsPure(condition.Flags)) - return false; - // The test is the leftmost operand of a left-nested chain of `&`. - while (condition is BinaryNumericInstruction { Operator: BinaryNumericOperator.BitAnd } and) - { - if (MatchTypeTest(and.Left, exceptionVar, out exceptionType)) - { - typeTest = and; - return true; - } - condition = and.Left; - } - return false; - } - - /// - /// comp(isinst T(ldloc exceptionVar) != ldnull), however the compiler spelled the null test. - /// - static bool MatchTypeTest(ILInstruction condition, ILVariable exceptionVar, out IType exceptionType) - { - exceptionType = null; - if (condition is not Comp comp || !comp.Right.MatchLdNull()) - return false; - // `cgt.un x, null` is how both compilers spell `x != null` for a reference. - if (comp.Kind != ComparisonKind.Inequality - && !(comp.Kind == ComparisonKind.GreaterThan && comp.InputType == StackType.O)) - return false; - if (!comp.Left.MatchIsInst(out var argument, out exceptionType)) - return false; - return argument.MatchLdLoc(exceptionVar); - } - /// /// catch E_189 : 0200007C System.Exception when (BlockContainer { /// Block IL_0079 (incoming: 1) {