diff --git a/.gitignore b/.gitignore index e5dcba17b..ee15307eb 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ _ReSharper*/ .vs/ /ILSpy.AddIn/Packages/* /ICSharpCode.Decompiler.Tests/TestCases/Correctness/*.exe +/ICSharpCode.Decompiler.Tests/TestCases/Correctness/*.exe.config /ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec diff --git a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs index b72db5422..d9488b7d0 100644 --- a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs @@ -39,7 +39,7 @@ namespace ICSharpCode.Decompiler.Tests .Select(m => m.Name) .ToArray(); foreach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles()) { - if (file.Extension == ".txt" || file.Extension == ".exe") + if (file.Extension == ".txt" || file.Extension == ".exe" || file.Extension == ".config") continue; var testName = Path.GetFileNameWithoutExtension(file.Name); Assert.Contains(testName, testNames); @@ -130,9 +130,6 @@ namespace ICSharpCode.Decompiler.Tests [Test] public void Loops([ValueSource("defaultOptions")] CompilerOptions options) { - if (options.HasFlag(CompilerOptions.UseMcs)) { - Assert.Ignore("Decompiler bug with mono!"); - } RunCS(options: options); } @@ -296,6 +293,20 @@ namespace ICSharpCode.Decompiler.Tests outputFile = Tester.CompileCSharp(Path.Combine(TestCasePath, testFileName), options, outputFileName: Path.Combine(TestCasePath, testOutputFileName)); string decompiledCodeFile = Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options)); + if (options.HasFlag(CompilerOptions.UseMcs)) { + // For second pass, use roslyn instead of mcs. + // mcs has some compiler bugs that cause it to not accept ILSpy-generated code, + // for example when there's unreachable code due to other compiler bugs in the first mcs run. + options &= ~CompilerOptions.UseMcs; + options |= CompilerOptions.UseRoslyn; + // Also, add an .exe.config so that we consistently use the .NET 4.x runtime. + File.WriteAllText(outputFile.PathToAssembly + ".config", @" + + + + +"); + } decompiledOutputFile = Tester.CompileCSharp(decompiledCodeFile, options); Tester.RunAndCompareOutput(testFileName, outputFile.PathToAssembly, decompiledOutputFile.PathToAssembly, decompiledCodeFile); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Comparisons.cs b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Comparisons.cs index 48277108e..276d75223 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Comparisons.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Comparisons.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Globalization; #pragma warning disable 652 @@ -55,7 +56,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness float[] vals = { -1, 0, 3, float.PositiveInfinity, float.NaN }; for (int i = 0; i < vals.Length; i++) { for (int j = 0; j < vals.Length; j++) { - Console.WriteLine("Float: {0:r} {1} {2:r} = {3}", vals[i], name, vals[j], f(vals[i], vals[j])); + Console.WriteLine("Float: {0} {1} {2:r} = {3}", + vals[i].ToString("r", CultureInfo.InvariantCulture), + name, + vals[j].ToString("r", CultureInfo.InvariantCulture), + f(vals[i], vals[j])); } } } diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs b/ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs index 6e336377e..1cc34d494 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs @@ -155,6 +155,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow } // Remove return blocks that are no longer reachable: container.Blocks.RemoveAll(b => b.IncomingEdgeCount == 0 && b.Instructions.Count == 0); + if (context.Settings.RemoveDeadCode) { + container.SortBlocks(deleteUnreachableBlocks: true); + } } }