diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index bec77f0d6..ddb15c1d5 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -73,6 +73,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index 3636325ec..ed2abf072 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -220,6 +220,12 @@ namespace ICSharpCode.Decompiler.Tests RunForLibrary(cscOptions: cscOptions); } + [Test] + public void ConstructorInitializers([ValueSource(nameof(defaultOptionsWithMcs))] CSharpCompilerOptions cscOptions) + { + RunForLibrary(cscOptions: cscOptions); + } + [Test] public void PInvoke([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.cs new file mode 100644 index 000000000..9b2a7d175 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.cs @@ -0,0 +1,35 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +{ + public class ConstructorInitializers + { + public struct SimpleStruct + { + public int Field1; + public int Field2; + } + + public class UnsafeFields + { + public unsafe static int StaticSizeOf = sizeof(SimpleStruct); + public unsafe int SizeOf = sizeof(SimpleStruct); + } + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.il new file mode 100644 index 000000000..a8d0edf46 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.il @@ -0,0 +1,88 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly ConstructorInitializers +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module ConstructorInitializers.dll +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit SimpleStruct + extends [mscorlib]System.ValueType + { + .field public int32 Field1 + .field public int32 Field2 + } // end of class SimpleStruct + + .class auto ansi nested public beforefieldinit UnsafeFields + extends [mscorlib]System.Object + { + .field public static int32 StaticSizeOf + .field public int32 SizeOf + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 20 (0x14) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0007: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::SizeOf + IL_000c: ldarg.0 + IL_000d: call instance void [mscorlib]System.Object::.ctor() + IL_0012: nop + IL_0013: ret + } // end of method UnsafeFields::.ctor + + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 12 (0xc) + .maxstack 8 + IL_0000: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0006: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::StaticSizeOf + IL_000b: ret + } // end of method UnsafeFields::.cctor + + } // end of class UnsafeFields + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method ConstructorInitializers::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.mcs.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.mcs.il new file mode 100644 index 000000000..5fed2ec8d --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.mcs.il @@ -0,0 +1,120 @@ + + + + +// Metadata version: v2.0.50727 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly ConstructorInitializers.mcs +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + .permissionset reqmin + bytearray (3C 00 50 00 65 00 72 00 6D 00 69 00 73 00 73 00 // <.P.e.r.m.i.s.s. + 69 00 6F 00 6E 00 53 00 65 00 74 00 20 00 63 00 // i.o.n.S.e.t. .c. + 6C 00 61 00 73 00 73 00 3D 00 22 00 53 00 79 00 // l.a.s.s.=.".S.y. + 73 00 74 00 65 00 6D 00 2E 00 53 00 65 00 63 00 // s.t.e.m...S.e.c. + 75 00 72 00 69 00 74 00 79 00 2E 00 50 00 65 00 // u.r.i.t.y...P.e. + 72 00 6D 00 69 00 73 00 73 00 69 00 6F 00 6E 00 // r.m.i.s.s.i.o.n. + 53 00 65 00 74 00 22 00 0D 00 0A 00 76 00 65 00 // S.e.t.".....v.e. + 72 00 73 00 69 00 6F 00 6E 00 3D 00 22 00 31 00 // r.s.i.o.n.=.".1. + 22 00 3E 00 0D 00 0A 00 3C 00 49 00 50 00 65 00 // ".>.....<.I.P.e. + 72 00 6D 00 69 00 73 00 73 00 69 00 6F 00 6E 00 // r.m.i.s.s.i.o.n. + 20 00 63 00 6C 00 61 00 73 00 73 00 3D 00 22 00 // .c.l.a.s.s.=.". + 53 00 79 00 73 00 74 00 65 00 6D 00 2E 00 53 00 // S.y.s.t.e.m...S. + 65 00 63 00 75 00 72 00 69 00 74 00 79 00 2E 00 // e.c.u.r.i.t.y... + 50 00 65 00 72 00 6D 00 69 00 73 00 73 00 69 00 // P.e.r.m.i.s.s.i. + 6F 00 6E 00 73 00 2E 00 53 00 65 00 63 00 75 00 // o.n.s...S.e.c.u. + 72 00 69 00 74 00 79 00 50 00 65 00 72 00 6D 00 // r.i.t.y.P.e.r.m. + 69 00 73 00 73 00 69 00 6F 00 6E 00 2C 00 20 00 // i.s.s.i.o.n.,. . + 6D 00 73 00 63 00 6F 00 72 00 6C 00 69 00 62 00 // m.s.c.o.r.l.i.b. + 2C 00 20 00 56 00 65 00 72 00 73 00 69 00 6F 00 // ,. .V.e.r.s.i.o. + 6E 00 3D 00 32 00 2E 00 30 00 2E 00 30 00 2E 00 // n.=.2...0...0... + 30 00 2C 00 20 00 43 00 75 00 6C 00 74 00 75 00 // 0.,. .C.u.l.t.u. + 72 00 65 00 3D 00 6E 00 65 00 75 00 74 00 72 00 // r.e.=.n.e.u.t.r. + 61 00 6C 00 2C 00 20 00 50 00 75 00 62 00 6C 00 // a.l.,. .P.u.b.l. + 69 00 63 00 4B 00 65 00 79 00 54 00 6F 00 6B 00 // i.c.K.e.y.T.o.k. + 65 00 6E 00 3D 00 62 00 37 00 37 00 61 00 35 00 // e.n.=.b.7.7.a.5. + 63 00 35 00 36 00 31 00 39 00 33 00 34 00 65 00 // c.5.6.1.9.3.4.e. + 30 00 38 00 39 00 22 00 0D 00 0A 00 76 00 65 00 // 0.8.9.".....v.e. + 72 00 73 00 69 00 6F 00 6E 00 3D 00 22 00 31 00 // r.s.i.o.n.=.".1. + 22 00 0D 00 0A 00 46 00 6C 00 61 00 67 00 73 00 // ".....F.l.a.g.s. + 3D 00 22 00 53 00 6B 00 69 00 70 00 56 00 65 00 // =.".S.k.i.p.V.e. + 72 00 69 00 66 00 69 00 63 00 61 00 74 00 69 00 // r.i.f.i.c.a.t.i. + 6F 00 6E 00 22 00 2F 00 3E 00 0D 00 0A 00 3C 00 // o.n."./.>.....<. + 2F 00 50 00 65 00 72 00 6D 00 69 00 73 00 73 00 // /.P.e.r.m.i.s.s. + 69 00 6F 00 6E 00 53 00 65 00 74 00 3E 00 0D 00 // i.o.n.S.e.t.>... + 0A 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module ConstructorInitializers.mcs.dll +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit SimpleStruct + extends [mscorlib]System.ValueType + { + .field public int32 Field1 + .field public int32 Field2 + } // end of class SimpleStruct + + .class auto ansi nested public beforefieldinit UnsafeFields + extends [mscorlib]System.Object + { + .field public static int32 StaticSizeOf + .field public int32 SizeOf + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 19 (0x13) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0007: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::SizeOf + IL_000c: ldarg.0 + IL_000d: call instance void [mscorlib]System.Object::.ctor() + IL_0012: ret + } // end of method UnsafeFields::.ctor + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 12 (0xc) + .maxstack 8 + IL_0000: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0006: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::StaticSizeOf + IL_000b: ret + } // end of method UnsafeFields::.cctor + + } // end of class UnsafeFields + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method ConstructorInitializers::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.opt.il new file mode 100644 index 000000000..f96a7d44e --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.opt.il @@ -0,0 +1,87 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly ConstructorInitializers.opt +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module ConstructorInitializers.opt.dll +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit SimpleStruct + extends [mscorlib]System.ValueType + { + .field public int32 Field1 + .field public int32 Field2 + } // end of class SimpleStruct + + .class auto ansi nested public beforefieldinit UnsafeFields + extends [mscorlib]System.Object + { + .field public static int32 StaticSizeOf + .field public int32 SizeOf + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 19 (0x13) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0007: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::SizeOf + IL_000c: ldarg.0 + IL_000d: call instance void [mscorlib]System.Object::.ctor() + IL_0012: ret + } // end of method UnsafeFields::.ctor + + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 12 (0xc) + .maxstack 8 + IL_0000: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0006: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::StaticSizeOf + IL_000b: ret + } // end of method UnsafeFields::.cctor + + } // end of class UnsafeFields + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method ConstructorInitializers::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.opt.mcs.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.opt.mcs.il new file mode 100644 index 000000000..186747841 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.opt.mcs.il @@ -0,0 +1,120 @@ + + + + +// Metadata version: v2.0.50727 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly ConstructorInitializers.opt.mcs +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + .permissionset reqmin + bytearray (3C 00 50 00 65 00 72 00 6D 00 69 00 73 00 73 00 // <.P.e.r.m.i.s.s. + 69 00 6F 00 6E 00 53 00 65 00 74 00 20 00 63 00 // i.o.n.S.e.t. .c. + 6C 00 61 00 73 00 73 00 3D 00 22 00 53 00 79 00 // l.a.s.s.=.".S.y. + 73 00 74 00 65 00 6D 00 2E 00 53 00 65 00 63 00 // s.t.e.m...S.e.c. + 75 00 72 00 69 00 74 00 79 00 2E 00 50 00 65 00 // u.r.i.t.y...P.e. + 72 00 6D 00 69 00 73 00 73 00 69 00 6F 00 6E 00 // r.m.i.s.s.i.o.n. + 53 00 65 00 74 00 22 00 0D 00 0A 00 76 00 65 00 // S.e.t.".....v.e. + 72 00 73 00 69 00 6F 00 6E 00 3D 00 22 00 31 00 // r.s.i.o.n.=.".1. + 22 00 3E 00 0D 00 0A 00 3C 00 49 00 50 00 65 00 // ".>.....<.I.P.e. + 72 00 6D 00 69 00 73 00 73 00 69 00 6F 00 6E 00 // r.m.i.s.s.i.o.n. + 20 00 63 00 6C 00 61 00 73 00 73 00 3D 00 22 00 // .c.l.a.s.s.=.". + 53 00 79 00 73 00 74 00 65 00 6D 00 2E 00 53 00 // S.y.s.t.e.m...S. + 65 00 63 00 75 00 72 00 69 00 74 00 79 00 2E 00 // e.c.u.r.i.t.y... + 50 00 65 00 72 00 6D 00 69 00 73 00 73 00 69 00 // P.e.r.m.i.s.s.i. + 6F 00 6E 00 73 00 2E 00 53 00 65 00 63 00 75 00 // o.n.s...S.e.c.u. + 72 00 69 00 74 00 79 00 50 00 65 00 72 00 6D 00 // r.i.t.y.P.e.r.m. + 69 00 73 00 73 00 69 00 6F 00 6E 00 2C 00 20 00 // i.s.s.i.o.n.,. . + 6D 00 73 00 63 00 6F 00 72 00 6C 00 69 00 62 00 // m.s.c.o.r.l.i.b. + 2C 00 20 00 56 00 65 00 72 00 73 00 69 00 6F 00 // ,. .V.e.r.s.i.o. + 6E 00 3D 00 32 00 2E 00 30 00 2E 00 30 00 2E 00 // n.=.2...0...0... + 30 00 2C 00 20 00 43 00 75 00 6C 00 74 00 75 00 // 0.,. .C.u.l.t.u. + 72 00 65 00 3D 00 6E 00 65 00 75 00 74 00 72 00 // r.e.=.n.e.u.t.r. + 61 00 6C 00 2C 00 20 00 50 00 75 00 62 00 6C 00 // a.l.,. .P.u.b.l. + 69 00 63 00 4B 00 65 00 79 00 54 00 6F 00 6B 00 // i.c.K.e.y.T.o.k. + 65 00 6E 00 3D 00 62 00 37 00 37 00 61 00 35 00 // e.n.=.b.7.7.a.5. + 63 00 35 00 36 00 31 00 39 00 33 00 34 00 65 00 // c.5.6.1.9.3.4.e. + 30 00 38 00 39 00 22 00 0D 00 0A 00 76 00 65 00 // 0.8.9.".....v.e. + 72 00 73 00 69 00 6F 00 6E 00 3D 00 22 00 31 00 // r.s.i.o.n.=.".1. + 22 00 0D 00 0A 00 46 00 6C 00 61 00 67 00 73 00 // ".....F.l.a.g.s. + 3D 00 22 00 53 00 6B 00 69 00 70 00 56 00 65 00 // =.".S.k.i.p.V.e. + 72 00 69 00 66 00 69 00 63 00 61 00 74 00 69 00 // r.i.f.i.c.a.t.i. + 6F 00 6E 00 22 00 2F 00 3E 00 0D 00 0A 00 3C 00 // o.n."./.>.....<. + 2F 00 50 00 65 00 72 00 6D 00 69 00 73 00 73 00 // /.P.e.r.m.i.s.s. + 69 00 6F 00 6E 00 53 00 65 00 74 00 3E 00 0D 00 // i.o.n.S.e.t.>... + 0A 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module ConstructorInitializers.opt.mcs.dll +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit SimpleStruct + extends [mscorlib]System.ValueType + { + .field public int32 Field1 + .field public int32 Field2 + } // end of class SimpleStruct + + .class auto ansi nested public beforefieldinit UnsafeFields + extends [mscorlib]System.Object + { + .field public static int32 StaticSizeOf + .field public int32 SizeOf + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 19 (0x13) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0007: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::SizeOf + IL_000c: ldarg.0 + IL_000d: call instance void [mscorlib]System.Object::.ctor() + IL_0012: ret + } // end of method UnsafeFields::.ctor + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 12 (0xc) + .maxstack 8 + IL_0000: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0006: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::StaticSizeOf + IL_000b: ret + } // end of method UnsafeFields::.cctor + + } // end of class UnsafeFields + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method ConstructorInitializers::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.opt.roslyn.il new file mode 100644 index 000000000..fd488e45d --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.opt.roslyn.il @@ -0,0 +1,91 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly ConstructorInitializers +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module ConstructorInitializers.dll +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit SimpleStruct + extends [mscorlib]System.ValueType + { + .field public int32 Field1 + .field public int32 Field2 + } // end of class SimpleStruct + + .class auto ansi nested public beforefieldinit UnsafeFields + extends [mscorlib]System.Object + { + .field public static int32 StaticSizeOf + .field public int32 SizeOf + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 19 (0x13) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0007: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::SizeOf + IL_000c: ldarg.0 + IL_000d: call instance void [mscorlib]System.Object::.ctor() + IL_0012: ret + } // end of method UnsafeFields::.ctor + + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 12 (0xc) + .maxstack 8 + IL_0000: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0006: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::StaticSizeOf + IL_000b: ret + } // end of method UnsafeFields::.cctor + + } // end of class UnsafeFields + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method ConstructorInitializers::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.roslyn.il new file mode 100644 index 000000000..e18de96fc --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.roslyn.il @@ -0,0 +1,93 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly ConstructorInitializers +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module ConstructorInitializers.dll +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit SimpleStruct + extends [mscorlib]System.ValueType + { + .field public int32 Field1 + .field public int32 Field2 + } // end of class SimpleStruct + + .class auto ansi nested public beforefieldinit UnsafeFields + extends [mscorlib]System.Object + { + .field public static int32 StaticSizeOf + .field public int32 SizeOf + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 20 (0x14) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0007: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::SizeOf + IL_000c: ldarg.0 + IL_000d: call instance void [mscorlib]System.Object::.ctor() + IL_0012: nop + IL_0013: ret + } // end of method UnsafeFields::.ctor + + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 12 (0xc) + .maxstack 8 + IL_0000: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/SimpleStruct + IL_0006: stsfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers/UnsafeFields::StaticSizeOf + IL_000b: ret + } // end of method UnsafeFields::.cctor + + } // end of class UnsafeFields + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method ConstructorInitializers::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ConstructorInitializers + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs b/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs index 4b330a949..b87bf717a 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs @@ -122,6 +122,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms var ctorMethodDef = instanceCtorsNotChainingWithThis[0].GetSymbol() as IMethod; if (ctorMethodDef != null && ctorMethodDef.DeclaringType.IsReferenceType == false) return; + + bool ctorIsUnsafe = instanceCtorsNotChainingWithThis.All(c => c.HasModifier(Modifiers.Unsafe)); // Recognize field or property initializers: // Translate first statement in all ctors (if all ctors have the same statement) into an initializer. @@ -133,7 +135,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms IMember fieldOrPropertyOrEvent = (m.Get("fieldAccess").Single().GetSymbol() as IMember)?.MemberDefinition; if (!(fieldOrPropertyOrEvent is IField) && !(fieldOrPropertyOrEvent is IProperty) && !(fieldOrPropertyOrEvent is IEvent)) break; - AstNode fieldOrPropertyOrEventDecl = members.FirstOrDefault(f => f.GetSymbol() == fieldOrPropertyOrEvent); + var fieldOrPropertyOrEventDecl = members.FirstOrDefault(f => f.GetSymbol() == fieldOrPropertyOrEvent) as EntityDeclaration; // Cannot transform if member is not found or if it is a custom event. if (fieldOrPropertyOrEventDecl == null || fieldOrPropertyOrEventDecl is CustomEventDeclaration) break; @@ -158,6 +160,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms if (allSame) { foreach (var ctor in instanceCtorsNotChainingWithThis) ctor.Body.First().Remove(); + if (ctorIsUnsafe && IntroduceUnsafeModifier.IsUnsafe(initializer)) { + fieldOrPropertyOrEventDecl.Modifiers |= Modifiers.Unsafe; + } if (fieldOrPropertyOrEventDecl is PropertyDeclaration pd) { pd.Initializer = initializer.Detach(); } else { @@ -175,6 +180,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms if (instanceCtors.Length == 1 && (members.Skip(1).Any() || instanceCtors[0].Parent is TypeDeclaration)) { ConstructorDeclaration emptyCtor = new ConstructorDeclaration(); emptyCtor.Modifiers = contextTypeDefinition.IsAbstract ? Modifiers.Protected : Modifiers.Public; + if (instanceCtors[0].HasModifier(Modifiers.Unsafe)) + emptyCtor.Modifiers |= Modifiers.Unsafe; emptyCtor.Body = new BlockStatement(); if (emptyCtor.IsMatch(instanceCtors[0])) instanceCtors[0].Remove(); @@ -186,6 +193,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms // Translate static constructor into field initializers if the class is BeforeFieldInit var staticCtor = members.OfType().FirstOrDefault(c => (c.Modifiers & Modifiers.Static) == Modifiers.Static); if (staticCtor != null) { + bool ctorIsUnsafe = staticCtor.HasModifier(Modifiers.Unsafe); IMethod ctorMethod = staticCtor.GetSymbol() as IMethod; if (!ctorMethod.MetadataToken.IsNil) { var metadata = context.TypeSystem.MainModule.PEFile.Metadata; @@ -202,9 +210,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms IMember fieldOrProperty = (assignment.Left.GetSymbol() as IMember)?.MemberDefinition; if (!(fieldOrProperty is IField || fieldOrProperty is IProperty) || !fieldOrProperty.IsStatic) break; - AstNode fieldOrPropertyDecl = members.FirstOrDefault(f => f.GetSymbol() == fieldOrProperty); + var fieldOrPropertyDecl = members.FirstOrDefault(f => f.GetSymbol() == fieldOrProperty) as EntityDeclaration; if (fieldOrPropertyDecl == null) break; + if (ctorIsUnsafe && IntroduceUnsafeModifier.IsUnsafe(assignment.Right)) { + fieldOrPropertyDecl.Modifiers |= Modifiers.Unsafe; + } if (fieldOrPropertyDecl is FieldDeclaration fd) fd.Variables.Single().Initializer = assignment.Right.Detach(); else if (fieldOrPropertyDecl is PropertyDeclaration pd) diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs index 8882a7277..03e08bba6 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs @@ -29,6 +29,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms { compilationUnit.AcceptVisitor(this); } + + public static bool IsUnsafe(AstNode node) + { + return node.AcceptVisitor(new IntroduceUnsafeModifier()); + } protected override bool VisitChildren(AstNode node) {