diff --git a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs index cd774b27f..13a882986 100644 --- a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs @@ -156,10 +156,15 @@ namespace ICSharpCode.Decompiler.Tests } [Test] - public void BitNot() + public void BitNot([Values(false, true)] bool force32Bit) { - RunIL("BitNot.il"); - RunIL("BitNot.il", CompilerOptions.UseDebug | CompilerOptions.Force32Bit, AssemblerOptions.Force32Bit); + CompilerOptions compiler = CompilerOptions.UseDebug; + AssemblerOptions asm = AssemblerOptions.None; + if (force32Bit) { + compiler |= CompilerOptions.Force32Bit; + asm |= AssemblerOptions.Force32Bit; + } + RunIL("BitNot.il", compiler, asm); } [Test] @@ -168,6 +173,18 @@ namespace ICSharpCode.Decompiler.Tests RunIL("Jmp.il"); } + [Test] + public void StackTypes([Values(false, true)] bool force32Bit) + { + CompilerOptions compiler = CompilerOptions.UseDebug; + AssemblerOptions asm = AssemblerOptions.None; + if (force32Bit) { + compiler |= CompilerOptions.Force32Bit; + asm |= AssemblerOptions.Force32Bit; + } + RunIL("StackTypes.il", compiler, asm); + } + [Test] public void UnsafeCode([ValueSource("defaultOptions")] CompilerOptions options) { @@ -209,7 +226,7 @@ namespace ICSharpCode.Decompiler.Tests { RunCS(options: options); } - + void RunCS([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug) { string testFileName = testName + ".cs"; diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs index 05de0357e..f75d79759 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs @@ -67,6 +67,10 @@ namespace ICSharpCode.Decompiler.Tests.Helpers string ilasmPath = Path.Combine(Environment.GetEnvironmentVariable("windir"), @"Microsoft.NET\Framework\v4.0.30319\ilasm.exe"); string outputFile = Path.Combine(Path.GetDirectoryName(sourceFileName), Path.GetFileNameWithoutExtension(sourceFileName)); string otherOptions = " "; + if (options.HasFlag(AssemblerOptions.Force32Bit)) { + outputFile += ".32"; + otherOptions += "/32BitPreferred "; + } if (options.HasFlag(AssemblerOptions.Library)) { outputFile += ".dll"; otherOptions += "/dll "; @@ -79,9 +83,6 @@ namespace ICSharpCode.Decompiler.Tests.Helpers if (options.HasFlag(AssemblerOptions.UseDebug)) { otherOptions += "/debug "; } - if (options.HasFlag(AssemblerOptions.Force32Bit)) { - otherOptions += "/32BitPreferred "; - } ProcessStartInfo info = new ProcessStartInfo(ilasmPath); info.Arguments = $"/nologo {otherOptions}/output=\"{outputFile}\" \"{sourceFileName}\""; diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 856000b84..adb328120 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -45,6 +45,7 @@ + @@ -134,12 +135,6 @@ - - HelloWorld.cs - - - InlineAssignmentTest.cs - diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/StackTypes.il b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/StackTypes.il new file mode 100644 index 000000000..bb66d1596 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/StackTypes.il @@ -0,0 +1,218 @@ +.assembly extern mscorlib +{ + .publickeytoken = ( b7 7a 5c 56 19 34 e0 89 ) + .ver 4:0:0:0 +} + +.assembly 'StackTypes' +{ + .ver 0:0:0:0 +} + +.module StackTypes.exe +.corflags 0x00000001 // ILOnly + +.class private auto ansi abstract sealed beforefieldinit Program +extends [mscorlib]System.Object +{ + .method public hidebysig static void Main (string[] args) cil managed + { + .maxstack 8 + .entrypoint + + //call void Program::Int32OrNativeTests() + + ret + } // end of method Main + + /* + .method public static void Int32OrNativeTests() + { + ldstr "Int32OrNative(0x7fffffff, false) = {0}" + ldc.i4 0x7fffffff + ldc.i4 0 + call native int Program::Int32OrNative(int32, bool) + box native int + call void [mscorlib]System.Console::WriteLine(string, object) + + ldstr "Int32OrNative(0x7fffffff, true) = {0}" + ldc.i4 0x7fffffff + ldc.i4 1 + call native int Program::Int32OrNative(int32, bool) + box native int + call void [mscorlib]System.Console::WriteLine(string, object) + + ldstr "Int32OrNative(-1, false) = {0}" + ldc.i4.m1 + ldc.i4 0 + call native int Program::Int32OrNative(int32, bool) + box native int + call void [mscorlib]System.Console::WriteLine(string, object) + + ldstr "Int32OrNative(-1, true) = {0}" + ldc.i4.m1 + ldc.i4 1 + call native int Program::Int32OrNative(int32, bool) + box native int + call void [mscorlib]System.Console::WriteLine(string, object) + + ldstr "Int32OrNativeLoopStyle(0x7fffffff):" + call void [mscorlib]System.Console::WriteLine(string) + ldc.i4 0x7fffffff + call void Program::Int32OrNativeLoopStyle(int32) + + ldstr "Int32OrNativeLoopStyle(-1):" + call void [mscorlib]System.Console::WriteLine(string) + ldc.i4.m1 + call void Program::Int32OrNativeLoopStyle(int32) + + ldstr "Int32OrNativeDeadCode(0x7fffffff) = {0}" + ldc.i4 0x7fffffff + call native int Program::Int32OrNativeDeadCode(int32) + box native int + call void [mscorlib]System.Console::WriteLine(string, object) + + ldstr "Int32OrNativeDeadCode(-1) = {0}" + ldc.i4.m1 + call native int Program::Int32OrNativeDeadCode(int32) + box native int + call void [mscorlib]System.Console::WriteLine(string, object) + + ldc.i4 0x7fffffff + call void Program::RunInt32OrNativeMultiUse(int32) + ldc.i4.m1 + call void Program::RunInt32OrNativeMultiUse(int32) + + ret + } + .method public static native int Int32OrNative(int32 val, bool use_native) + { + ldarg.1 + brtrue use_native_int + use_i4: + ldarg.0 + br after_if + after_if: + ldc.i4.1 + add + ret + use_native_int: + ldarg.0 + conv.u + br after_if + } + + .method public static void Int32OrNativeLoopStyle(int32 val) + { + .locals init ( + int32 i + ) + ldarg.0 + loop: + ldc.i4.1 + add + call void Program::Print(native int) + ldloc.0 + brtrue end + + ldc.i4.1 + stloc.0 + ldarg.0 + conv.u + br loop + end: + ret + } + + .method public static native int Int32OrNativeDeadCode(int32 val) + { + use_i4: + ldarg.0 + br after_if + after_if: + ldc.i4.1 + add + ret + use_native_int: // dead code + ldarg.0 + conv.u + br after_if + } + + .method public static void RunInt32OrNativeMultiUse(int32 val) + { + ldstr "RunInt32OrNativeMultiUse({0}, push_i: false, use2: false) = {1}" + ldarg val + box int32 + ldarg val + ldc.i4 0 // push_i + ldc.i4 0 // use2 + call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2) + box native int + call void [mscorlib]System.Console::WriteLine(string, object, object) + + ldstr "RunInt32OrNativeMultiUse({0}, push_i: false, use2: true) = {1}" + ldarg val + box int32 + ldarg val + ldc.i4 0 // push_i + ldc.i4 1 // use2 + call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2) + box native int + call void [mscorlib]System.Console::WriteLine(string, object, object) + + ldstr "RunInt32OrNativeMultiUse({0}, push_i: true, use2: false) = {1}" + ldarg val + box int32 + ldarg val + ldc.i4 1 // push_i + ldc.i4 0 // use2 + call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2) + box native int + call void [mscorlib]System.Console::WriteLine(string, object, object) + + ldstr "RunInt32OrNativeMultiUse({0}, push_i: true, use2: true) = {1}" + ldarg val + box int32 + ldarg val + ldc.i4 1 // push_i + ldc.i4 1 // use2 + call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2) + box native int + call void [mscorlib]System.Console::WriteLine(string, object, object) + ret + } + + .method public static native int Int32OrNativeMultiUse(int32 val, bool push_i, bool use2) + { + ldarg.1 + brtrue push_i + br push_i4 + push_i4: + ldarg.0 + ldarg.2 + brtrue use2 + br use1 + push_i: + ldarg.0 + conv.u + br use1 + use1: + ldc.i4.1 + add + ret + use2: + ldc.i4.2 + add + ret + } + */ + + .method public static void Print(native int val) + { + ldarg.0 + box native int + call void [mscorlib]System.Console::WriteLine(object) + ret + } +}