diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs index ed9e2739f..4583a5fae 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs @@ -69,6 +69,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers UseTestRunner = 0x4000, NullableEnable = 0x8000, ReferenceUnsafe = 0x10000, + CheckForOverflowUnderflow = 0x20000, UseMcsMask = UseMcs2_6_4 | UseMcs5_23, UseRoslynMask = UseRoslyn1_3_2 | UseRoslyn2_10_0 | UseRoslyn3_11_0 | UseRoslynLatest } @@ -543,6 +544,16 @@ namespace System.Runtime.CompilerServices { otherOptions += "-platform:anycpu "; } + + if (flags.HasFlag(CompilerOptions.CheckForOverflowUnderflow)) + { + otherOptions += "-checked+ "; + } + else + { + otherOptions += "-checked- "; + } + if (preprocessorSymbols.Count > 0) { otherOptions += " \"-d:" + string.Join(";", preprocessorSymbols) + "\" "; diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index f7c49347a..728769fde 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -141,6 +141,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index b528cd65b..25c5e0191 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -635,6 +635,12 @@ namespace ICSharpCode.Decompiler.Tests await RunForLibrary(cscOptions: cscOptions); } + [Test] + public async Task Issue3483([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) + { + await RunForLibrary(cscOptions: cscOptions | CompilerOptions.CheckForOverflowUnderflow, configureDecompiler: settings => settings.CheckForOverflowUnderflow = true); + } + [Test] public async Task AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3483.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3483.cs new file mode 100644 index 000000000..2a13df92b --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3483.cs @@ -0,0 +1,44 @@ +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +{ + internal static class Issue3483 + { + public static int Add_Checked(int x, int y) + { + return x + y; + } + public static int Add_Unchecked(int x, int y) + { + return unchecked(x + y); + } + public static int Add_CheckedAndUnchecked_1(int x, int y, int z) + { + return x + unchecked(y + z); + } + public static int Add_CheckedAndUnchecked_2(int x, int y, int z) + { + unchecked + { + return x + checked(y + z); + } + } + public static uint Cast_Checked(int x) + { + return (uint)x; + } + public static uint Cast_Unchecked(int x) + { + return unchecked((uint)x); + } + public static int Cast_CheckedAndUnchecked_1(int x) + { + return (int)unchecked((uint)x); + } + public static int Cast_CheckedAndUnchecked_2(int x) + { + unchecked + { + return (int)checked((uint)x); + } + } + } +} diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/AddCheckedBlocks.cs b/ICSharpCode.Decompiler/CSharp/Transforms/AddCheckedBlocks.cs index 7ffaf24e4..881ad6f09 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/AddCheckedBlocks.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/AddCheckedBlocks.cs @@ -252,8 +252,14 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms else { Result r = GetResultFromBlock(block); - if (r.NodesToInsertInUncheckedContext != null) - r.NodesToInsertInUncheckedContext.Insert(); + if (context.DecompileRun.Settings.CheckForOverflowUnderflow) + { + r.NodesToInsertInCheckedContext?.Insert(); + } + else + { + r.NodesToInsertInUncheckedContext?.Insert(); + } } } diff --git a/ICSharpCode.Decompiler/DecompilerSettings.cs b/ICSharpCode.Decompiler/DecompilerSettings.cs index a0bd68f36..02bfd027c 100644 --- a/ICSharpCode.Decompiler/DecompilerSettings.cs +++ b/ICSharpCode.Decompiler/DecompilerSettings.cs @@ -2185,6 +2185,24 @@ namespace ICSharpCode.Decompiler } } + bool checkForOverflowUnderflow = false; + + /// + /// Check for overflow and underflow in operators. + /// + [Category("DecompilerSettings.Other")] + [Description("DecompilerSettings.CheckForOverflowUnderflow")] + public bool CheckForOverflowUnderflow { + get { return checkForOverflowUnderflow; } + set { + if (checkForOverflowUnderflow != value) + { + checkForOverflowUnderflow = value; + OnPropertyChanged(); + } + } + } + CSharpFormattingOptions csharpFormattingOptions; [Browsable(false)] diff --git a/ILSpy/Properties/Resources.Designer.cs b/ILSpy/Properties/Resources.Designer.cs index cb59e0a29..d51f6e4b1 100644 --- a/ILSpy/Properties/Resources.Designer.cs +++ b/ILSpy/Properties/Resources.Designer.cs @@ -810,6 +810,15 @@ namespace ICSharpCode.ILSpy.Properties { } } + /// + /// Looks up a localized string similar to Check for overflow and underflow in operators. + /// + public static string DecompilerSettings_CheckForOverflowUnderflow { + get { + return ResourceManager.GetString("DecompilerSettings.CheckForOverflowUnderflow", resourceCulture); + } + } + /// /// Looks up a localized string similar to Decompile anonymous methods/lambdas. /// @@ -1127,16 +1136,6 @@ namespace ICSharpCode.ILSpy.Properties { } } - /// - /// Looks up a localized resource of type System.Object. - /// - public static object DecompilerSettings_LifetimeAnnotations { - get { - object obj = ResourceManager.GetObject("DecompilerSettings.LifetimeAnnotations", resourceCulture); - return ((object)(obj)); - } - } - /// /// Looks up a localized string similar to Use nint/nuint types. /// diff --git a/ILSpy/Properties/Resources.resx b/ILSpy/Properties/Resources.resx index 64871a33b..be83f54ed 100644 --- a/ILSpy/Properties/Resources.resx +++ b/ILSpy/Properties/Resources.resx @@ -288,6 +288,9 @@ Are you sure you want to continue? Automatically load assembly references + + Check for overflow and underflow in operators + User-defined checked operators diff --git a/ILSpy/Properties/Resources.zh-Hans.resx b/ILSpy/Properties/Resources.zh-Hans.resx index cae67ec78..8955a00ba 100644 --- a/ILSpy/Properties/Resources.zh-Hans.resx +++ b/ILSpy/Properties/Resources.zh-Hans.resx @@ -279,6 +279,9 @@ 反编译异步 IAsyncEnumerator 方法 + + + 反编译匿名方法或 lambda