Recognize a VB exception filter's type test
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
This commit is contained in:
1 parent
297a659cc0
commit
594bb08fca
4 files changed
+248
No files matched your search
@@ -0,0 +1,109 @@
|
||||
.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 '<Module>'
|
||||
{
|
||||
}
|
||||
|
||||
.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
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user