From 89083eaf48ca3cf1e151497803ff4fbcc013b135 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 23 Aug 2025 15:50:54 +0200 Subject: [PATCH] Fix #3344: Add support for the `ckfinite` opcode. --- .../ICSharpCode.Decompiler.Tests.csproj | 2 + .../ILPrettyTestRunner.cs | 6 +++ .../TestCases/ILPretty/Issue3344CkFinite.cs | 22 +++++++++ .../TestCases/ILPretty/Issue3344CkFinite.il | 48 +++++++++++++++++++ .../CSharp/StatementBuilder.cs | 27 +++++++++++ 5 files changed, 105 insertions(+) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3344CkFinite.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3344CkFinite.il diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 941e2d87c..c13352fec 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -100,6 +100,7 @@ + @@ -142,6 +143,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs index 2fc5bbc87..4bfbfb812 100644 --- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs @@ -207,6 +207,12 @@ namespace ICSharpCode.Decompiler.Tests await Run(); } + [Test] + public async Task Issue3344CkFinite() + { + await Run(); + } + [Test] public async Task Issue3421() { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3344CkFinite.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3344CkFinite.cs new file mode 100644 index 000000000..0f8e6287e --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3344CkFinite.cs @@ -0,0 +1,22 @@ +using System; + +namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty +{ + public class Issue3344 + { + private static float GetFloat() + { + return 3.5f; + } + + private static float CkFinite() + { + float num = GetFloat(); + if (!float.IsFinite(num)) + { + throw new ArithmeticException(); + } + return num; + } + } +} \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3344CkFinite.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3344CkFinite.il new file mode 100644 index 000000000..f5a0c84f9 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3344CkFinite.il @@ -0,0 +1,48 @@ +.assembly extern System.Runtime +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} + +.assembly Issue3344 +{ + .hash algorithm 0x00008004 // SHA1 + .ver 0:0:0:0 +} + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3344 + extends [System.Runtime]System.Object +{ + .method private hidebysig static + float32 GetFloat () cil managed + { + .maxstack 8 + + IL_0000: ldc.r4 3.5 + IL_0005: ret + } + + .method private hidebysig static + float32 CkFinite () cil managed + { + .maxstack 1 + .locals init ( + [0] float32 + ) + + call float32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3344::GetFloat() + ckfinite + ret + } + + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: call instance void [System.Runtime]System.Object::.ctor() + IL_0006: ret + } + +} \ No newline at end of file diff --git a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs index 3e8dba558..d3f1cc838 100644 --- a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs @@ -1542,5 +1542,32 @@ namespace ICSharpCode.Decompiler.CSharp stmt.InsertChildAfter(null, new Comment(" IL cpblk instruction"), Roles.Comment); return stmt.WithILInstruction(inst); } + + protected internal override TranslatedStatement VisitCkfinite(Ckfinite inst) + { + var isFiniteCall = new InvocationExpression { + Target = new MemberReferenceExpression { + Target = new TypeReferenceExpression(new Syntax.PrimitiveType("float")), + MemberName = "IsFinite" + }, + Arguments = { + exprBuilder.Translate(inst.Argument) + } + }; + var arithmeticException = typeSystem.FindType(typeof(ArithmeticException)); + var arithmeticExceptionSyntax = new SimpleType("ArithmeticException"); + arithmeticExceptionSyntax.AddAnnotation(new TypeResolveResult(arithmeticException)); + return new IfElseStatement { + Condition = new UnaryOperatorExpression { + Operator = UnaryOperatorType.Not, + Expression = isFiniteCall + }, + TrueStatement = new ThrowStatement( + new ObjectCreateExpression { + Type = arithmeticExceptionSyntax + } + ), + }.WithILInstruction(inst); + } } }