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)
{