From 72e7db13fa940a09f052b90ffbabc224e2d319e0 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Sat, 10 Oct 2026 13:07:54 +0200 Subject: [PATCH] #4136: Simplify bool-typed if (c) 1 else 0 to c != 0 An IfInstruction tests its condition for non-zero, so a bool-typed `if (c) ldc.i4 1 else ldc.i4 0` always equals `c != 0`, which ExpressionTransforms already folds to `c` for bool `c`. Without this identity the node reached the C# output as `c ? true : false`, or as `c || 1 == 0` once negated. The lost `??` form is not addressed here. --- .../TestCases/Pretty/LiftedOperators.cs | 47 +++++++++++++++++++ .../IL/Transforms/ExpressionTransforms.cs | 11 +++++ 2 files changed, 58 insertions(+) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/LiftedOperators.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/LiftedOperators.cs index e92b8ba..3d02e5f 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/LiftedOperators.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/LiftedOperators.cs @@ -935,6 +935,53 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty //return (a + 1) ?? (b + 2) ?? (c + 3) ?? (d + 4); return 0L; } + +#if CS90 + private static IDisposable Open(int length) + { + return null; + } + + public static void NullOrZeroPatternBeforeUsing(int? num) + { +#if EXPECTED_OUTPUT + if (!num.HasValue || num.GetValueOrDefault() == 0) +#else + if (num is null or 0) +#endif + { + return; + } + using (Open(num.Value)) + { + Print(num.Value); + } + } + + public static void NullOrZeroPatternEarlyReturn(int? num) + { +#if EXPECTED_OUTPUT +#if OPT && !ROSLYN4 + if ((num ?? 0) != 0) +#else + if (num.HasValue && num.GetValueOrDefault() != 0) +#endif + { + Print(num); + Print(num.Value); + Print(num.Value + 1); + } +#else + if (num is null or 0) + { + return; + } + Print(num); + Print(num.Value); + Print(num.Value + 1); +#endif + } +#endif } internal class T04_LiftedCompoundAssignAndBoxing diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs index 1a29a00..259a5b4 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs @@ -584,6 +584,17 @@ namespace ICSharpCode.Decompiler.IL.Transforms context.EndStep(matchCondition); return; } + if (inst.TrueInst.MatchLdcI4(1) && inst.FalseInst.MatchLdcI4(0) + && inst.InferType(context.TypeSystem).IsKnownType(KnownTypeCode.Boolean)) + { + context.Step("if (c) true else false -> comp(c != 0)", inst); + var comp = new Comp(ComparisonKind.Inequality, Sign.None, inst.Condition, new LdcI4(0)); + comp.AddILRange(inst); + inst.ReplaceWith(comp); + context.EndStep(comp); + comp.AcceptVisitor(this); + return; + } } IfInstruction HandleConditionalOperator(IfInstruction inst)