diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs index 17b3a5f16..56bb762d0 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs @@ -329,6 +329,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { SimpleStruct* ptr = stackalloc SimpleStruct[checked(count * 2)]; SimpleStruct* ptr2 = stackalloc SimpleStruct[10]; + ptr->X = count; + ptr[1].X = ptr->X; + for (int i = 2; i < 10; i++) { + ptr[i].X = count; + } return this.UsePointer(&ptr->Y); } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il index e4d7a0692..65de1dfd2 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 veti52ie +.assembly '5mgf1rnb' { .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 veti52ie.dll -// MVID: {F873CF77-738D-4A61-B0C6-96B9F5621119} +.module '5mgf1rnb.dll' +// MVID: {C39B0AE8-69C3-4207-B912-FCEE701C71E8} .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: 0x028F0000 +// Image base: 0x00C60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -1238,11 +1238,13 @@ .method public hidebysig instance string StackAllocStruct(int32 count) cil managed { - // Code size 46 (0x2e) - .maxstack 2 + // Code size 110 (0x6e) + .maxstack 3 .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0, valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_1, - string V_2) + int32 V_2, + string V_3, + bool V_4) IL_0000: nop IL_0001: ldarg.1 IL_0002: ldc.i4.2 @@ -1258,16 +1260,50 @@ IL_0018: mul.ovf.un IL_0019: localloc IL_001b: stloc.1 - IL_001c: ldarg.0 - IL_001d: ldloc.0 - IL_001e: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y - IL_0023: conv.u - IL_0024: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) - IL_0029: stloc.2 - IL_002a: br.s IL_002c - - IL_002c: ldloc.2 - IL_002d: ret + IL_001c: ldloc.0 + IL_001d: ldarg.1 + IL_001e: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0023: ldloc.0 + IL_0024: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_002a: add + IL_002b: ldloc.0 + IL_002c: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0031: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0036: ldc.i4.2 + IL_0037: stloc.2 + IL_0038: br.s IL_0051 + + IL_003a: nop + IL_003b: ldloc.0 + IL_003c: ldloc.2 + IL_003d: conv.i + IL_003e: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0044: mul + IL_0045: add + IL_0046: ldarg.1 + IL_0047: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_004c: nop + IL_004d: ldloc.2 + IL_004e: ldc.i4.1 + IL_004f: add + IL_0050: stloc.2 + IL_0051: ldloc.2 + IL_0052: ldc.i4.s 10 + IL_0054: clt + IL_0056: stloc.s V_4 + IL_0058: ldloc.s V_4 + IL_005a: brtrue.s IL_003a + + IL_005c: ldarg.0 + IL_005d: ldloc.0 + IL_005e: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y + IL_0063: conv.u + IL_0064: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_0069: stloc.3 + IL_006a: br.s IL_006c + + IL_006c: ldloc.3 + IL_006d: ret } // end of method UnsafeCode::StackAllocStruct .method family hidebysig virtual instance void diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il index 96247420b..1a0b0ea04 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 '24yl5hoc' +.assembly av3nix0s { .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 '24yl5hoc.dll' -// MVID: {73FF4D49-1CDC-4675-A00D-0D382845C323} +.module av3nix0s.dll +// MVID: {3E5B8427-2816-45EA-9E7A-139AA9452535} .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: 0x013A0000 +// Image base: 0x025C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -986,9 +986,10 @@ .method public hidebysig instance string StackAllocStruct(int32 count) cil managed { - // Code size 41 (0x29) - .maxstack 2 - .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0) + // Code size 97 (0x61) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0, + int32 V_1) IL_0000: ldarg.1 IL_0001: ldc.i4.2 IL_0002: mul.ovf @@ -1003,12 +1004,41 @@ IL_0017: mul.ovf.un IL_0018: localloc IL_001a: pop - IL_001b: ldarg.0 - IL_001c: ldloc.0 - IL_001d: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y - IL_0022: conv.u - IL_0023: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) - IL_0028: ret + IL_001b: ldloc.0 + IL_001c: ldarg.1 + IL_001d: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0022: ldloc.0 + IL_0023: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0029: add + IL_002a: ldloc.0 + IL_002b: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0030: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0035: ldc.i4.2 + IL_0036: stloc.1 + IL_0037: br.s IL_004e + + IL_0039: ldloc.0 + IL_003a: ldloc.1 + IL_003b: conv.i + IL_003c: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0042: mul + IL_0043: add + IL_0044: ldarg.1 + IL_0045: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_004a: ldloc.1 + IL_004b: ldc.i4.1 + IL_004c: add + IL_004d: stloc.1 + IL_004e: ldloc.1 + IL_004f: ldc.i4.s 10 + IL_0051: blt.s IL_0039 + + IL_0053: ldarg.0 + IL_0054: ldloc.0 + IL_0055: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y + IL_005a: conv.u + IL_005b: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_0060: ret } // end of method UnsafeCode::StackAllocStruct .method family hidebysig virtual instance void diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il index a4831768c..19c2a8b81 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: {DD1630B5-221C-4D3A-8171-7BFFD65CA0F2} +// MVID: {6E613246-08C3-4B77-B500-576D8782513A} .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: 0x01320000 +// Image base: 0x030D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -991,9 +991,10 @@ .method public hidebysig instance string StackAllocStruct(int32 count) cil managed { - // Code size 41 (0x29) - .maxstack 2 - .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0) + // Code size 97 (0x61) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0, + int32 V_1) IL_0000: ldarg.1 IL_0001: ldc.i4.2 IL_0002: mul.ovf @@ -1008,12 +1009,41 @@ IL_0017: mul.ovf.un IL_0018: localloc IL_001a: pop - IL_001b: ldarg.0 - IL_001c: ldloc.0 - IL_001d: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y - IL_0022: conv.u - IL_0023: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) - IL_0028: ret + IL_001b: ldloc.0 + IL_001c: ldarg.1 + IL_001d: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0022: ldloc.0 + IL_0023: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0029: add + IL_002a: ldloc.0 + IL_002b: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0030: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0035: ldc.i4.2 + IL_0036: stloc.1 + IL_0037: br.s IL_004e + + IL_0039: ldloc.0 + IL_003a: ldloc.1 + IL_003b: conv.i + IL_003c: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0042: mul + IL_0043: add + IL_0044: ldarg.1 + IL_0045: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_004a: ldloc.1 + IL_004b: ldc.i4.1 + IL_004c: add + IL_004d: stloc.1 + IL_004e: ldloc.1 + IL_004f: ldc.i4.s 10 + IL_0051: blt.s IL_0039 + + IL_0053: ldarg.0 + IL_0054: ldloc.0 + IL_0055: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y + IL_005a: conv.u + IL_005b: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_0060: ret } // end of method UnsafeCode::StackAllocStruct .method family hidebysig virtual instance void diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il index 8cee9896b..d1f786100 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: {34A4C476-B60D-4D44-9CF4-288026720E1B} +// MVID: {E02FB293-0E44-4F82-B549-8BAB6E8A9750} .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: 0x00AC0000 +// Image base: 0x006B0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -1242,11 +1242,13 @@ .method public hidebysig instance string StackAllocStruct(int32 count) cil managed { - // Code size 46 (0x2e) - .maxstack 2 + // Code size 110 (0x6e) + .maxstack 3 .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0, valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_1, - string V_2) + int32 V_2, + bool V_3, + string V_4) IL_0000: nop IL_0001: ldarg.1 IL_0002: ldc.i4.2 @@ -1262,16 +1264,50 @@ IL_0018: mul.ovf.un IL_0019: localloc IL_001b: stloc.1 - IL_001c: ldarg.0 - IL_001d: ldloc.0 - IL_001e: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y - IL_0023: conv.u - IL_0024: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) - IL_0029: stloc.2 - IL_002a: br.s IL_002c - - IL_002c: ldloc.2 - IL_002d: ret + IL_001c: ldloc.0 + IL_001d: ldarg.1 + IL_001e: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0023: ldloc.0 + IL_0024: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_002a: add + IL_002b: ldloc.0 + IL_002c: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0031: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0036: ldc.i4.2 + IL_0037: stloc.2 + IL_0038: br.s IL_0051 + + IL_003a: nop + IL_003b: ldloc.0 + IL_003c: ldloc.2 + IL_003d: conv.i + IL_003e: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0044: mul + IL_0045: add + IL_0046: ldarg.1 + IL_0047: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_004c: nop + IL_004d: ldloc.2 + IL_004e: ldc.i4.1 + IL_004f: add + IL_0050: stloc.2 + IL_0051: ldloc.2 + IL_0052: ldc.i4.s 10 + IL_0054: clt + IL_0056: stloc.3 + IL_0057: ldloc.3 + IL_0058: brtrue.s IL_003a + + IL_005a: ldarg.0 + IL_005b: ldloc.0 + IL_005c: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y + IL_0061: conv.u + IL_0062: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_0067: stloc.s V_4 + IL_0069: br.s IL_006b + + IL_006b: ldloc.s V_4 + IL_006d: ret } // end of method UnsafeCode::StackAllocStruct .method family hidebysig virtual instance void diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index e4a161bce..7053ed8eb 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -810,6 +810,10 @@ namespace ICSharpCode.Decompiler.CSharp } return Translate(countOffsetInst); } + } else if (byteOffsetInst.UnwrapConv(ConversionKind.SignExtend) is SizeOf sizeOf && sizeOf.Type.Equals(pointerType.ElementType)) { + return new PrimitiveExpression(1) + .WithILInstruction(byteOffsetInst) + .WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 1)); } else if (byteOffsetInst.MatchLdcI(out long val)) { // If the offset is a constant, it's possible that the compiler // constant-folded the multiplication. @@ -1540,9 +1544,14 @@ namespace ICSharpCode.Decompiler.CSharp if (!TypeUtils.IsCompatibleTypeForMemoryAccess(target.Type, inst.Type)) { target = target.ConvertTo(new PointerType(inst.Type), this); } - result = new UnaryOperatorExpression(UnaryOperatorType.Dereference, target.Expression) - .WithoutILInstruction() - .WithRR(new ResolveResult(((TypeWithElementType)target.Type).ElementType)); + if (target.Expression is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.AddressOf) { + // *&ptr -> ptr + result = target.UnwrapChild(uoe.Expression); + } else { + result = new UnaryOperatorExpression(UnaryOperatorType.Dereference, target.Expression) + .WithoutILInstruction() + .WithRR(new ResolveResult(((TypeWithElementType)target.Type).ElementType)); + } } var value = Translate(inst.Value, typeHint: result.Type); return Assignment(result, value).WithILInstruction(inst);