mirror of https://github.com/icsharpcode/ILSpy.git
Browse Source
vbc builds an exception filter as a single non-short-circuiting
expression: `isinst`, then the user's `when` conditions, combined with
`and`. DetectCatchWhenConditionBlocks only knew the branch chain csc
emits, so the type test stayed inside the filter and the handler kept the
`object` variable it has in IL:
catch (object obj) when ((obj is Exception) & (num2 != 0) & (num == 0))
{
ProjectData.SetProjectError((Exception)obj);
A catch type has to derive from Exception, so that does not compile.
The conjunction form is matched too now, lifting the test to the catch
type as the block form already does. The other conjuncts stop running for
a non-matching exception once the test moves, so the filter has to be
pure for this to be invisible; PropagateExceptionVariable then drops the
castclass in the handler:
catch (Exception ex) when ((num2 != 0) & (num == 0))
{
ProjectData.SetProjectError(ex);
Closes #3659
pull/4134/head
5 changed files with 184 additions and 0 deletions
@ -0,0 +1,91 @@
@@ -0,0 +1,91 @@
|
||||
using System; |
||||
using System.Runtime.CompilerServices; |
||||
using Microsoft.VisualBasic.CompilerServices; |
||||
|
||||
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) |
||||
{ |
||||
#if OPT || LEGACY_VBC
|
||||
int try0000_dispatch = -1; |
||||
#else
|
||||
int try0001_dispatch = -1; |
||||
#endif
|
||||
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*/; |
||||
#if OPT || LEGACY_VBC
|
||||
switch (try0000_dispatch) |
||||
#else
|
||||
switch (try0001_dispatch) |
||||
#endif
|
||||
{ |
||||
default: |
||||
{ |
||||
ProjectData.ClearProjectError(); |
||||
num2 = 2; |
||||
Issue3659 obj = this; |
||||
Func(ref obj, RuntimeHelpers.GetObjectValue(value)); |
||||
#if OPT || LEGACY_VBC
|
||||
goto end_IL_0000; |
||||
#else
|
||||
goto end_IL_0001; |
||||
#endif
|
||||
} |
||||
#if OPT || LEGACY_VBC
|
||||
case 45: |
||||
#else
|
||||
case 50: |
||||
#endif
|
||||
num = -1; |
||||
switch (num2) |
||||
{ |
||||
case 2: |
||||
ShowMessage("VBFunction", 0, "Exception", null, 0); |
||||
#if OPT || LEGACY_VBC
|
||||
goto end_IL_0000; |
||||
#else
|
||||
goto end_IL_0001; |
||||
#endif
|
||||
} |
||||
break; |
||||
} |
||||
} |
||||
catch (Exception ex) when ((num2 != 0) & (num == 0)) |
||||
{ |
||||
ProjectData.SetProjectError(ex); |
||||
#if OPT || LEGACY_VBC
|
||||
try0000_dispatch = 45; |
||||
#else
|
||||
try0001_dispatch = 50; |
||||
#endif
|
||||
continue; |
||||
} |
||||
throw ProjectData.CreateProjectError(-2146828237); |
||||
continue; |
||||
#if OPT || LEGACY_VBC
|
||||
end_IL_0000: |
||||
#else
|
||||
end_IL_0001: |
||||
#endif
|
||||
break; |
||||
} |
||||
if (num != 0) |
||||
{ |
||||
ProjectData.ClearProjectError(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
Imports System |
||||
Public Class Issue3659 |
||||
Public Shared Sub Func(ByRef obj As Issue3659, value As Object) |
||||
End Sub |
||||
|
||||
Public Shared Function ShowMessage(a As String, b As Integer, c As String, d As Object, e As Integer) As Integer |
||||
Return 0 |
||||
End Function |
||||
|
||||
Friend Sub VBFunction(value As Object) |
||||
On Error GoTo Handler |
||||
Func(Me, value) |
||||
Exit Sub |
||||
Handler: |
||||
ShowMessage("VBFunction", 0, "Exception", Nothing, 0) |
||||
End Sub |
||||
End Class |
||||
Loading…
Reference in new issue