diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs index dcbf9d7d1..17b3a5f16 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs @@ -129,14 +129,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public unsafe void PassRefParameterAsPointer(ref int p) { - fixed (int* p2 = &p) { - this.PassPointerAsRefParameter(p2); + fixed (int* ptr = &p) { + this.UsePointer(ptr); } } public unsafe void PassPointerAsRefParameter(int* p) { - this.PassRefParameterAsPointer(ref *p); + this.UseReference(ref *p); } public unsafe void AddressInMultiDimensionalArray(double[,] matrix) @@ -282,6 +282,33 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty return m->Doubles; } + public unsafe void UseFixedMemberAsPointer(StructWithFixedSizeMembers* m) + { + this.UsePointer(m->Integers); + } + + public unsafe void UseFixedMemberAsReference(StructWithFixedSizeMembers* m) + { + this.UseReference(ref *m->Integers); + this.UseReference(ref m->Integers[1]); + } + + public unsafe void PinFixedMember(ref StructWithFixedSizeMembers m) + { + fixed (int* ptr = m.Integers) { + this.UsePointer(ptr); + } + } + + private void UseReference(ref int i) + { + } + + public unsafe string UsePointer(int* ptr) + { + return ptr->ToString(); + } + public unsafe string UsePointer(double* ptr) { return ptr->ToString(); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il index 4dd480085..e4d7a0692 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly ob0irbmp +.assembly veti52ie { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module ob0irbmp.dll -// MVID: {72C21E04-2476-45C2-824E-E862E52B73A5} +.module veti52ie.dll +// MVID: {F873CF77-738D-4A61-B0C6-96B9F5621119} .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 -// Image base: 0x02DA0000 +// Image base: 0x028F0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -422,8 +422,8 @@ IL_0004: ldarg.0 IL_0005: ldloc.0 IL_0006: conv.i - IL_0007: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) - IL_000c: nop + IL_0007: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_000c: pop IL_000d: nop IL_000e: ldc.i4.0 IL_000f: conv.u @@ -439,7 +439,7 @@ IL_0000: nop IL_0001: ldarg.0 IL_0002: ldarg.1 - IL_0003: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassRefParameterAsPointer(int32&) + IL_0003: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) IL_0008: nop IL_0009: ret } // end of method UnsafeCode::PassPointerAsRefParameter @@ -1061,6 +1061,97 @@ IL_0011: ret } // end of method UnsafeCode::FixedMemberBasePointer + .method public hidebysig instance void + UseFixedMemberAsPointer(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 21 (0x15) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0008: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0'::FixedElementField + IL_000d: conv.u + IL_000e: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_0013: pop + IL_0014: ret + } // end of method UnsafeCode::UseFixedMemberAsPointer + + .method public hidebysig instance void + UseFixedMemberAsReference(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 43 (0x2b) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0008: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0'::FixedElementField + IL_000d: conv.u + IL_000e: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) + IL_0013: nop + IL_0014: ldarg.0 + IL_0015: ldarg.1 + IL_0016: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_001b: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0'::FixedElementField + IL_0020: conv.u + IL_0021: ldc.i4.4 + IL_0022: conv.i + IL_0023: add + IL_0024: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) + IL_0029: nop + IL_002a: ret + } // end of method UnsafeCode::UseFixedMemberAsReference + + .method public hidebysig instance void + PinFixedMember(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers& m) cil managed + { + // Code size 28 (0x1c) + .maxstack 2 + .locals init (int32& pinned V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0007: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0'::FixedElementField + IL_000c: stloc.0 + IL_000d: nop + IL_000e: ldarg.0 + IL_000f: ldloc.0 + IL_0010: conv.i + IL_0011: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_0016: pop + IL_0017: nop + IL_0018: ldc.i4.0 + IL_0019: conv.u + IL_001a: stloc.0 + IL_001b: ret + } // end of method UnsafeCode::PinFixedMember + + .method private hidebysig instance void + UseReference(int32& i) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method UnsafeCode::UseReference + + .method public hidebysig instance string + UsePointer(int32* ptr) cil managed + { + // Code size 12 (0xc) + .maxstack 1 + .locals init (string V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: call instance string [mscorlib]System.Int32::ToString() + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::UsePointer + .method public hidebysig instance string UsePointer(float64* ptr) cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il index 49e03fec3..96247420b 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly gqg3tz14 +.assembly '24yl5hoc' { .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 @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module gqg3tz14.dll -// MVID: {F3C49182-FFB5-41E4-933E-7530556E64D8} +.module '24yl5hoc.dll' +// MVID: {73FF4D49-1CDC-4675-A00D-0D382845C323} .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 -// Image base: 0x00960000 +// Image base: 0x013A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -347,7 +347,7 @@ .method public hidebysig instance void PassRefParameterAsPointer(int32& p) cil managed { - // Code size 14 (0xe) + // Code size 15 (0xf) .maxstack 2 .locals init (int32& pinned V_0) IL_0000: ldarg.1 @@ -355,11 +355,12 @@ IL_0002: ldarg.0 IL_0003: ldloc.0 IL_0004: conv.i - IL_0005: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) - IL_000a: ldc.i4.0 - IL_000b: conv.u - IL_000c: stloc.0 - IL_000d: ret + IL_0005: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_000a: pop + IL_000b: ldc.i4.0 + IL_000c: conv.u + IL_000d: stloc.0 + IL_000e: ret } // end of method UnsafeCode::PassRefParameterAsPointer .method public hidebysig instance void @@ -369,7 +370,7 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassRefParameterAsPointer(int32&) + IL_0002: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) IL_0007: ret } // end of method UnsafeCode::PassPointerAsRefParameter @@ -840,6 +841,83 @@ IL_000c: ret } // end of method UnsafeCode::FixedMemberBasePointer + .method public hidebysig instance void + UseFixedMemberAsPointer(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 20 (0x14) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0007: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0'::FixedElementField + IL_000c: conv.u + IL_000d: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_0012: pop + IL_0013: ret + } // end of method UnsafeCode::UseFixedMemberAsPointer + + .method public hidebysig instance void + UseFixedMemberAsReference(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 40 (0x28) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0007: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0'::FixedElementField + IL_000c: conv.u + IL_000d: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) + IL_0012: ldarg.0 + IL_0013: ldarg.1 + IL_0014: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0019: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0'::FixedElementField + IL_001e: conv.u + IL_001f: ldc.i4.4 + IL_0020: conv.i + IL_0021: add + IL_0022: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) + IL_0027: ret + } // end of method UnsafeCode::UseFixedMemberAsReference + + .method public hidebysig instance void + PinFixedMember(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers& m) cil managed + { + // Code size 25 (0x19) + .maxstack 2 + .locals init (int32& pinned V_0) + IL_0000: ldarg.1 + IL_0001: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0006: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0'::FixedElementField + IL_000b: stloc.0 + IL_000c: ldarg.0 + IL_000d: ldloc.0 + IL_000e: conv.i + IL_000f: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_0014: pop + IL_0015: ldc.i4.0 + IL_0016: conv.u + IL_0017: stloc.0 + IL_0018: ret + } // end of method UnsafeCode::PinFixedMember + + .method private hidebysig instance void + UseReference(int32& i) cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method UnsafeCode::UseReference + + .method public hidebysig instance string + UsePointer(int32* ptr) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: call instance string [mscorlib]System.Int32::ToString() + IL_0006: ret + } // end of method UnsafeCode::UsePointer + .method public hidebysig instance string UsePointer(float64* ptr) cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il index 32ecd1769..a4831768c 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module UnsafeCode.dll -// MVID: {CBE9626D-F9BD-4008-A325-BABE72F089C1} +// MVID: {DD1630B5-221C-4D3A-8171-7BFFD65CA0F2} .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 -// Image base: 0x01600000 +// Image base: 0x01320000 // =============== CLASS MEMBERS DECLARATION =================== @@ -350,7 +350,7 @@ .method public hidebysig instance void PassRefParameterAsPointer(int32& p) cil managed { - // Code size 14 (0xe) + // Code size 15 (0xf) .maxstack 2 .locals init (int32& pinned V_0) IL_0000: ldarg.1 @@ -358,11 +358,12 @@ IL_0002: ldarg.0 IL_0003: ldloc.0 IL_0004: conv.i - IL_0005: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) - IL_000a: ldc.i4.0 - IL_000b: conv.u - IL_000c: stloc.0 - IL_000d: ret + IL_0005: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_000a: pop + IL_000b: ldc.i4.0 + IL_000c: conv.u + IL_000d: stloc.0 + IL_000e: ret } // end of method UnsafeCode::PassRefParameterAsPointer .method public hidebysig instance void @@ -372,7 +373,7 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassRefParameterAsPointer(int32&) + IL_0002: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) IL_0007: ret } // end of method UnsafeCode::PassPointerAsRefParameter @@ -846,6 +847,82 @@ IL_000c: ret } // end of method UnsafeCode::FixedMemberBasePointer + .method public hidebysig instance void + UseFixedMemberAsPointer(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 20 (0x14) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0007: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_000c: conv.u + IL_000d: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_0012: pop + IL_0013: ret + } // end of method UnsafeCode::UseFixedMemberAsPointer + + .method public hidebysig instance void + UseFixedMemberAsReference(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0007: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_000c: conv.u + IL_000d: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) + IL_0012: ldarg.0 + IL_0013: ldarg.1 + IL_0014: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0019: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_001e: conv.u + IL_001f: ldc.i4.4 + IL_0020: add + IL_0021: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) + IL_0026: ret + } // end of method UnsafeCode::UseFixedMemberAsReference + + .method public hidebysig instance void + PinFixedMember(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers& m) cil managed + { + // Code size 25 (0x19) + .maxstack 2 + .locals init (int32& pinned V_0) + IL_0000: ldarg.1 + IL_0001: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0006: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_000b: stloc.0 + IL_000c: ldarg.0 + IL_000d: ldloc.0 + IL_000e: conv.i + IL_000f: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_0014: pop + IL_0015: ldc.i4.0 + IL_0016: conv.u + IL_0017: stloc.0 + IL_0018: ret + } // end of method UnsafeCode::PinFixedMember + + .method private hidebysig instance void + UseReference(int32& i) cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method UnsafeCode::UseReference + + .method public hidebysig instance string + UsePointer(int32* ptr) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: call instance string [mscorlib]System.Int32::ToString() + IL_0006: ret + } // end of method UnsafeCode::UsePointer + .method public hidebysig instance string UsePointer(float64* ptr) cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il index 2b953ba30..8cee9896b 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module UnsafeCode.dll -// MVID: {DD8EC7AC-2A00-4D24-83E2-D39C3E04AE41} +// MVID: {34A4C476-B60D-4D44-9CF4-288026720E1B} .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 -// Image base: 0x01090000 +// Image base: 0x00AC0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -424,8 +424,8 @@ IL_0004: ldarg.0 IL_0005: ldloc.0 IL_0006: conv.i - IL_0007: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) - IL_000c: nop + IL_0007: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_000c: pop IL_000d: nop IL_000e: ldc.i4.0 IL_000f: conv.u @@ -441,7 +441,7 @@ IL_0000: nop IL_0001: ldarg.0 IL_0002: ldarg.1 - IL_0003: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassRefParameterAsPointer(int32&) + IL_0003: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) IL_0008: nop IL_0009: ret } // end of method UnsafeCode::PassPointerAsRefParameter @@ -1066,6 +1066,96 @@ IL_0011: ret } // end of method UnsafeCode::FixedMemberBasePointer + .method public hidebysig instance void + UseFixedMemberAsPointer(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 21 (0x15) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0008: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_000d: conv.u + IL_000e: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_0013: pop + IL_0014: ret + } // end of method UnsafeCode::UseFixedMemberAsPointer + + .method public hidebysig instance void + UseFixedMemberAsReference(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 42 (0x2a) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0008: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_000d: conv.u + IL_000e: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) + IL_0013: nop + IL_0014: ldarg.0 + IL_0015: ldarg.1 + IL_0016: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_001b: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_0020: conv.u + IL_0021: ldc.i4.4 + IL_0022: add + IL_0023: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseReference(int32&) + IL_0028: nop + IL_0029: ret + } // end of method UnsafeCode::UseFixedMemberAsReference + + .method public hidebysig instance void + PinFixedMember(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers& m) cil managed + { + // Code size 28 (0x1c) + .maxstack 2 + .locals init (int32& pinned V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0007: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_000c: stloc.0 + IL_000d: nop + IL_000e: ldarg.0 + IL_000f: ldloc.0 + IL_0010: conv.i + IL_0011: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(int32*) + IL_0016: pop + IL_0017: nop + IL_0018: ldc.i4.0 + IL_0019: conv.u + IL_001a: stloc.0 + IL_001b: ret + } // end of method UnsafeCode::PinFixedMember + + .method private hidebysig instance void + UseReference(int32& i) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method UnsafeCode::UseReference + + .method public hidebysig instance string + UsePointer(int32* ptr) cil managed + { + // Code size 12 (0xc) + .maxstack 1 + .locals init (string V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: call instance string [mscorlib]System.Int32::ToString() + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::UsePointer + .method public hidebysig instance string UsePointer(float64* ptr) cil managed { diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 13ff12ee8..e4a161bce 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1571,10 +1571,16 @@ namespace ICSharpCode.Decompiler.CSharp && inst.Target is LdFlda nestedLdFlda && CSharpDecompiler.IsFixedField(nestedLdFlda.Field, out var elementType, out _)) { - Expression result = ConvertField(nestedLdFlda.Field, nestedLdFlda.Target); - result.RemoveAnnotations(); - return result.WithRR(new ResolveResult(new PointerType(elementType))) + Expression fieldAccess = ConvertField(nestedLdFlda.Field, nestedLdFlda.Target); + fieldAccess.RemoveAnnotations(); + var result = fieldAccess.WithRR(new ResolveResult(new PointerType(elementType))) .WithILInstruction(inst); + if (inst.ResultType == StackType.Ref) { + // convert pointer back to ref + return result.ConvertTo(new ByReferenceType(elementType), this); + } else { + return result; + } } var expr = ConvertField(inst.Field, inst.Target).WithILInstruction(inst); if (inst.ResultType == StackType.I) { diff --git a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs index 2186a31b1..11d5a86b1 100644 --- a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs +++ b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs @@ -292,6 +292,11 @@ namespace ICSharpCode.Decompiler.CSharp // convert from reference to pointer Expression arg = ((DirectionExpression)Expression).Expression.Detach(); var pointerType = new PointerType(((ByReferenceType)type).ElementType); + if (arg is UnaryOperatorExpression argUOE && argUOE.Operator == UnaryOperatorType.Dereference) { + // &*ptr -> ptr + return new TranslatedExpression(argUOE).UnwrapChild(argUOE.Expression) + .ConvertTo(targetType, expressionBuilder); + } var pointerExpr = new UnaryOperatorExpression(UnaryOperatorType.AddressOf, arg) .WithILInstruction(this.ILInstructions) .WithRR(new ResolveResult(pointerType)); diff --git a/ICSharpCode.Decompiler/IL/Instructions/Block.cs b/ICSharpCode.Decompiler/IL/Instructions/Block.cs index 06cdc509b..480851e59 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Block.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Block.cs @@ -67,6 +67,9 @@ namespace ICSharpCode.Decompiler.IL /// /// /// Blocks in containers must have 'Nop' as a final instruction. + /// + /// Note that the FinalInstruction is included in Block.Children, + /// but not in Block.Instructions! /// public ILInstruction FinalInstruction { get {