From f8617a0c3d9f7bdb5e0a3ba587c940e6d7989048 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 3 Aug 2026 20:21:30 +0200 Subject: [PATCH] Print 0m instead of default(decimal) for zero decimal values decimal has no IL literal: legacy csc compiles 0m to a Decimal.Zero field load, which already decompiled to the literal, but Roslyn compiles it to a zero-initialization, which decompiled to default(decimal). The two forms are bit-identical for decimal, so the literal is no less faithful to the IL and matches what a human writes; it also removes the per-compiler split in the CompoundAssignmentTest fixture. Assisted-by: Claude:claude-fable-5:Claude Code --- .../ILPretty/Issue2260SwitchString.cs | 10 +++--- .../Pretty/CompoundAssignmentTest.cs | 36 ------------------- .../CSharp/ExpressionBuilder.cs | 7 ++++ 3 files changed, 12 insertions(+), 41 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue2260SwitchString.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue2260SwitchString.cs index 13989d0ec..97796482c 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue2260SwitchString.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue2260SwitchString.cs @@ -16,7 +16,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty break; case "stock_qty": { - decimal result2 = default(decimal); + decimal result2 = 0m; if (!decimal.TryParse(s, out result2)) { new object(); @@ -29,12 +29,12 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty } case "new_price": { - decimal num = default(decimal); + decimal num = 0m; break; } case "new_price4": { - decimal result4 = default(decimal); + decimal result4 = 0m; if (decimal.TryParse(s, out result4) && !(result4 < 0m)) { } @@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty } case "new_price1": { - decimal result3 = default(decimal); + decimal result3 = 0m; if (!decimal.TryParse(s, out result3)) { new object(); @@ -57,7 +57,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty } case "new_price2": { - decimal result = default(decimal); + decimal result = 0m; if (!decimal.TryParse(s, out result)) { new object(); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs index d135a801d..33d071564 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs @@ -4406,11 +4406,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty } public static void DecimalAddTest(decimal p, CustomClass c, CustomStruct2 s) { -#if LEGACY_CSC decimal num = 0m; -#else - decimal num = default(decimal); -#endif p += 5m; num += 5m; Use(ref num); @@ -4437,11 +4433,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public static void DecimalSubtractTest(decimal p, CustomClass c, CustomStruct2 s) { -#if LEGACY_CSC decimal num = 0m; -#else - decimal num = default(decimal); -#endif p -= 5m; num -= 5m; Use(ref num); @@ -4468,11 +4460,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public static void DecimalMultiplyTest(decimal p, CustomClass c, CustomStruct2 s) { -#if LEGACY_CSC decimal num = 0m; -#else - decimal num = default(decimal); -#endif p *= 5m; num *= 5m; Use(ref num); @@ -4499,11 +4487,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public static void DecimalDivideTest(decimal p, CustomClass c, CustomStruct2 s) { -#if LEGACY_CSC decimal num = 0m; -#else - decimal num = default(decimal); -#endif p /= 5m; num /= 5m; Use(ref num); @@ -4530,11 +4514,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public static void DecimalModulusTest(decimal p, CustomClass c, CustomStruct2 s) { -#if LEGACY_CSC decimal num = 0m; -#else - decimal num = default(decimal); -#endif p %= 5m; num %= 5m; Use(ref num); @@ -4561,11 +4541,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public static void DecimalPostIncTest(decimal p, CustomClass c, CustomStruct2 s) { -#if LEGACY_CSC decimal num = 0m; -#else - decimal num = default(decimal); -#endif X(p++); X(num++); Use(ref num); @@ -4592,11 +4568,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public static void DecimalPreIncTest(decimal p, CustomClass c, CustomStruct2 s) { -#if LEGACY_CSC decimal num = 0m; -#else - decimal num = default(decimal); -#endif X(++p); X(++num); Use(ref num); @@ -4622,11 +4594,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty } public static void DecimalPostDecTest(decimal p, CustomClass c, CustomStruct2 s) { -#if LEGACY_CSC decimal num = 0m; -#else - decimal num = default(decimal); -#endif X(p--); X(num--); Use(ref num); @@ -4653,11 +4621,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public static void DecimalPreDecTest(decimal p, CustomClass c, CustomStruct2 s) { -#if LEGACY_CSC decimal num = 0m; -#else - decimal num = default(decimal); -#endif X(--p); X(--num); Use(ref num); diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index bfb457be7..3df219962 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -697,6 +697,13 @@ namespace ICSharpCode.Decompiler.CSharp return new CastExpression(ConvertType(type), expr.WithRR(crr)) .WithRR(new ConversionResolveResult(type, crr, Conversion.NullLiteralConversion)); } + else if (type.IsKnownType(KnownTypeCode.Decimal)) + { + expr = new PrimitiveExpression(0m); + constantType = type; + constantValue = 0m; + return expr.WithRR(new ConstantResolveResult(constantType, constantValue)); + } else { expr = new DefaultValueExpression(ConvertType(type));