/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Emit2/Emit/ManagedAddressTests.cs
188 строк
7 KB
Youssef Victor
Parse pointer to arrays (#65432)
21 апр 2023, 13:51
Не верифицирован
21 апр 2023, 13:51
60987c3
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Emit { public class ManagedAddressTests : CSharpTestBase { [Fact] public void TestPointerToArray() { var source = """ using System; unsafe { var x = new[] { 0, 1, 2 }; int[]* xp = &x; var c = new C(xp); c.Print(); } public unsafe class C { private int[]* _x; public C(int[]* x) { _x = x; } public void Print() { int[] x = *_x; for (int i = 0; i < x.Length; i++) { Console.Write(x[i]); } } } """; var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe).VerifyDiagnostics( // (6,5): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('int[]') // int[]* xp = &x; Diagnostic(ErrorCode.WRN_ManagedAddr, "int[]*").WithArguments("int[]").WithLocation(6, 5), // (6,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('int[]') // int[]* xp = &x; Diagnostic(ErrorCode.WRN_ManagedAddr, "&x").WithArguments("int[]").WithLocation(6, 17), // (13,20): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('int[]') // private int[]* _x; Diagnostic(ErrorCode.WRN_ManagedAddr, "_x").WithArguments("int[]").WithLocation(13, 20), // (15,21): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('int[]') // public C(int[]* x) Diagnostic(ErrorCode.WRN_ManagedAddr, "x").WithArguments("int[]").WithLocation(15, 21) ); var verifier = CompileAndVerify(comp, expectedOutput: "012", verify: Verification.Fails with { ILVerifyMessage = """ [<Main>$]: Expected numeric type on the stack. { Offset = 0x12, Found = address of 'int32[]' } [.ctor]: Unmanaged pointers are not a verifiable type. { Offset = 0x9 } [Print]: Expected ByRef on the stack. { Offset = 0x7, Found = Native Int } """, PEVerifyMessage = """ [ : Program::<Main>$][offset 0x00000012][found address of ref ] Expected numeric type on the stack. [ : C::.ctor][offset 0x00000009] Unmanaged pointers are not a verifiable type. [ : C::Print][offset 0x00000007][found unmanaged pointer] Expected ByRef on the stack. """, }); verifier.VerifyMethodBody("<top-level-statements-entry-point>", """ { // Code size 36 (0x24) .maxstack 4 .locals init (int[] V_0, //x int[]* V_1, //xp C V_2) //c // sequence point: { IL_0000: nop // sequence point: var x = new[] { 0, 1, 2 }; IL_0001: ldc.i4.3 IL_0002: newarr "int" IL_0007: dup IL_0008: ldc.i4.1 IL_0009: ldc.i4.1 IL_000a: stelem.i4 IL_000b: dup IL_000c: ldc.i4.2 IL_000d: ldc.i4.2 IL_000e: stelem.i4 IL_000f: stloc.0 // sequence point: int[]* xp = &x; IL_0010: ldloca.s V_0 IL_0012: conv.u IL_0013: stloc.1 // sequence point: var c = new C(xp); IL_0014: ldloc.1 IL_0015: newobj "C..ctor(int[]*)" IL_001a: stloc.2 // sequence point: c.Print(); IL_001b: ldloc.2 IL_001c: callvirt "void C.Print()" IL_0021: nop // sequence point: } IL_0022: nop IL_0023: ret } """); verifier.VerifyMethodBody("C..ctor", """ { // Code size 16 (0x10) .maxstack 2 // sequence point: public C(int[]* x) IL_0000: ldarg.0 IL_0001: call "object..ctor()" IL_0006: nop // sequence point: { IL_0007: nop // sequence point: _x = x; IL_0008: ldarg.0 IL_0009: ldarg.1 IL_000a: stfld "int[]* C._x" // sequence point: } IL_000f: ret } """); verifier.VerifyMethodBody("C.Print", """ { // Code size 39 (0x27) .maxstack 2 .locals init (int[] V_0, //x int V_1, //i bool V_2) // sequence point: { IL_0000: nop // sequence point: int[] x = *_x; IL_0001: ldarg.0 IL_0002: ldfld "int[]* C._x" IL_0007: ldind.ref IL_0008: stloc.0 // sequence point: int i = 0 IL_0009: ldc.i4.0 IL_000a: stloc.1 // sequence point: <hidden> IL_000b: br.s IL_001c // sequence point: { IL_000d: nop // sequence point: Console.Write(x[i]); IL_000e: ldloc.0 IL_000f: ldloc.1 IL_0010: ldelem.i4 IL_0011: call "void System.Console.Write(int)" IL_0016: nop // sequence point: } IL_0017: nop // sequence point: i++ IL_0018: ldloc.1 IL_0019: ldc.i4.1 IL_001a: add IL_001b: stloc.1 // sequence point: i < x.Length IL_001c: ldloc.1 IL_001d: ldloc.0 IL_001e: ldlen IL_001f: conv.i4 IL_0020: clt IL_0022: stloc.2 // sequence point: <hidden> IL_0023: ldloc.2 IL_0024: brtrue.s IL_000d // sequence point: } IL_0026: ret } """); } } }