File: CodeGen\CodeGenStackAllocInitializerTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Emit\Microsoft.CodeAnalysis.CSharp.Emit.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Emit.UnitTests)
// 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.
 
#nullable disable
 
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
    [CompilerTrait(CompilerFeature.StackAllocInitializer)]
    public class CodeGenStackAllocInitializerTests : CompilingTestBase
    {
        [Fact]
        [WorkItem(29092, "https://github.com/dotnet/roslyn/issues/29092")]
        public void TestMixedWithInitBlock()
        {
 
            var text = @"
using System;
 
class Program
{
    static void Main(string[] args)
    {
        MakeBlock(1, 2, 3);
    }
 
    static unsafe void MakeBlock(int a, int b, int c)
    {
        int* ptr = stackalloc int[]
        {
           0, 0, 0, a, b, c
        };
        PrintBytes(ptr, 6);
    }
 
    static unsafe void PrintBytes(int* ptr, int count)
    {
        for (int i = 0; i < count; i++)
        {
            Console.Write(ptr[i]);
        }
    }
}";
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                expectedOutput: "000123",
                verify: Verification.Fails).VerifyIL("Program.MakeBlock",
@"{
  // Code size       42 (0x2a)
  .maxstack  4
  IL_0000:  ldc.i4.s   24
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  dup
  IL_0006:  ldc.i4.0
  IL_0007:  ldc.i4.s   24
  IL_0009:  initblk
  IL_000b:  dup
  IL_000c:  ldc.i4.3
  IL_000d:  conv.i
  IL_000e:  ldc.i4.4
  IL_000f:  mul
  IL_0010:  add
  IL_0011:  ldarg.0
  IL_0012:  stind.i4
  IL_0013:  dup
  IL_0014:  ldc.i4.4
  IL_0015:  conv.i
  IL_0016:  ldc.i4.4
  IL_0017:  mul
  IL_0018:  add
  IL_0019:  ldarg.1
  IL_001a:  stind.i4
  IL_001b:  dup
  IL_001c:  ldc.i4.5
  IL_001d:  conv.i
  IL_001e:  ldc.i4.4
  IL_001f:  mul
  IL_0020:  add
  IL_0021:  ldarg.2
  IL_0022:  stind.i4
  IL_0023:  ldc.i4.6
  IL_0024:  call       ""void Program.PrintBytes(int*, int)""
  IL_0029:  ret
}");
        }
 
        [Fact]
        public void TestUnmanaged_Pointer()
        {
            var text = @"
using System;
unsafe class Test
{
    static void Print<T>(T* p) where T : unmanaged
    {
        for (int i = 0; i < 3; i++)
            Console.Write(p[i]);
    }
 
    static void M<T>(T arg) where T : unmanaged
    {
        var obj1 = stackalloc T[3] { arg, arg, arg };
        Print<T>(obj1);
        var obj2 = stackalloc T[ ] { arg, arg, arg };
        Print<T>(obj2);
        var obj3 = stackalloc  [ ] { arg, arg, arg };
        Print<T>(obj3);
    }
 
    public static void Main()
    {
        M(42);
    }
}";
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                expectedOutput: "424242424242424242",
                verify: Verification.Fails).VerifyIL("Test.M<T>(T)",
@"{
  // Code size      163 (0xa3)
  .maxstack  4
  IL_0000:  ldc.i4.3
  IL_0001:  conv.u
  IL_0002:  sizeof     ""T""
  IL_0008:  mul.ovf.un
  IL_0009:  localloc
  IL_000b:  dup
  IL_000c:  ldarg.0
  IL_000d:  stobj      ""T""
  IL_0012:  dup
  IL_0013:  sizeof     ""T""
  IL_0019:  add
  IL_001a:  ldarg.0
  IL_001b:  stobj      ""T""
  IL_0020:  dup
  IL_0021:  ldc.i4.2
  IL_0022:  conv.i
  IL_0023:  sizeof     ""T""
  IL_0029:  mul
  IL_002a:  add
  IL_002b:  ldarg.0
  IL_002c:  stobj      ""T""
  IL_0031:  call       ""void Test.Print<T>(T*)""
  IL_0036:  ldc.i4.3
  IL_0037:  conv.u
  IL_0038:  sizeof     ""T""
  IL_003e:  mul.ovf.un
  IL_003f:  localloc
  IL_0041:  dup
  IL_0042:  ldarg.0
  IL_0043:  stobj      ""T""
  IL_0048:  dup
  IL_0049:  sizeof     ""T""
  IL_004f:  add
  IL_0050:  ldarg.0
  IL_0051:  stobj      ""T""
  IL_0056:  dup
  IL_0057:  ldc.i4.2
  IL_0058:  conv.i
  IL_0059:  sizeof     ""T""
  IL_005f:  mul
  IL_0060:  add
  IL_0061:  ldarg.0
  IL_0062:  stobj      ""T""
  IL_0067:  call       ""void Test.Print<T>(T*)""
  IL_006c:  ldc.i4.3
  IL_006d:  conv.u
  IL_006e:  sizeof     ""T""
  IL_0074:  mul.ovf.un
  IL_0075:  localloc
  IL_0077:  dup
  IL_0078:  ldarg.0
  IL_0079:  stobj      ""T""
  IL_007e:  dup
  IL_007f:  sizeof     ""T""
  IL_0085:  add
  IL_0086:  ldarg.0
  IL_0087:  stobj      ""T""
  IL_008c:  dup
  IL_008d:  ldc.i4.2
  IL_008e:  conv.i
  IL_008f:  sizeof     ""T""
  IL_0095:  mul
  IL_0096:  add
  IL_0097:  ldarg.0
  IL_0098:  stobj      ""T""
  IL_009d:  call       ""void Test.Print<T>(T*)""
  IL_00a2:  ret
}");
        }
 
        [Fact]
        public void TestUnmanaged_Span()
        {
            var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class Test
{
    public void M<T>(T arg) where T : unmanaged
    {
        Span<T> obj1 = stackalloc T[3] { arg, arg, arg };
        Span<T> obj2 = stackalloc T[ ] { arg, arg, arg };
        Span<T> obj3 = stackalloc  [ ] { arg, arg, arg };
    }
}
", options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3));
 
            CompileAndVerify(comp, verify: Verification.Fails).VerifyIL("Test.M<T>(T)",
@"{
  // Code size      169 (0xa9)
  .maxstack  4
  IL_0000:  ldc.i4.3
  IL_0001:  conv.u
  IL_0002:  sizeof     ""T""
  IL_0008:  mul.ovf.un
  IL_0009:  localloc
  IL_000b:  dup
  IL_000c:  ldarg.1
  IL_000d:  stobj      ""T""
  IL_0012:  dup
  IL_0013:  sizeof     ""T""
  IL_0019:  add
  IL_001a:  ldarg.1
  IL_001b:  stobj      ""T""
  IL_0020:  dup
  IL_0021:  ldc.i4.2
  IL_0022:  conv.i
  IL_0023:  sizeof     ""T""
  IL_0029:  mul
  IL_002a:  add
  IL_002b:  ldarg.1
  IL_002c:  stobj      ""T""
  IL_0031:  ldc.i4.3
  IL_0032:  newobj     ""System.Span<T>..ctor(void*, int)""
  IL_0037:  pop
  IL_0038:  ldc.i4.3
  IL_0039:  conv.u
  IL_003a:  sizeof     ""T""
  IL_0040:  mul.ovf.un
  IL_0041:  localloc
  IL_0043:  dup
  IL_0044:  ldarg.1
  IL_0045:  stobj      ""T""
  IL_004a:  dup
  IL_004b:  sizeof     ""T""
  IL_0051:  add
  IL_0052:  ldarg.1
  IL_0053:  stobj      ""T""
  IL_0058:  dup
  IL_0059:  ldc.i4.2
  IL_005a:  conv.i
  IL_005b:  sizeof     ""T""
  IL_0061:  mul
  IL_0062:  add
  IL_0063:  ldarg.1
  IL_0064:  stobj      ""T""
  IL_0069:  ldc.i4.3
  IL_006a:  newobj     ""System.Span<T>..ctor(void*, int)""
  IL_006f:  pop
  IL_0070:  ldc.i4.3
  IL_0071:  conv.u
  IL_0072:  sizeof     ""T""
  IL_0078:  mul.ovf.un
  IL_0079:  localloc
  IL_007b:  dup
  IL_007c:  ldarg.1
  IL_007d:  stobj      ""T""
  IL_0082:  dup
  IL_0083:  sizeof     ""T""
  IL_0089:  add
  IL_008a:  ldarg.1
  IL_008b:  stobj      ""T""
  IL_0090:  dup
  IL_0091:  ldc.i4.2
  IL_0092:  conv.i
  IL_0093:  sizeof     ""T""
  IL_0099:  mul
  IL_009a:  add
  IL_009b:  ldarg.1
  IL_009c:  stobj      ""T""
  IL_00a1:  ldc.i4.3
  IL_00a2:  newobj     ""System.Span<T>..ctor(void*, int)""
  IL_00a7:  pop
  IL_00a8:  ret
}");
        }
 
        [Fact]
        public void TestLambdaCapture()
        {
            var text = @"
using System;
public class C
{
    unsafe public static void Main() 
    {
        // captured by the lambda. 
        byte x = 1;
        byte* b = stackalloc byte[] {((Func<byte>)(() => x++))(), x};
        Console.Write(b[1]);
    }
}
";
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                expectedOutput: "2",
                verify: Verification.Fails).VerifyIL("C.Main",
@"{
  // Code size       55 (0x37)
  .maxstack  4
  .locals init (C.<>c__DisplayClass0_0 V_0) //CS$<>8__locals0
  IL_0000:  newobj     ""C.<>c__DisplayClass0_0..ctor()""
  IL_0005:  stloc.0
  IL_0006:  ldloc.0
  IL_0007:  ldc.i4.1
  IL_0008:  stfld      ""byte C.<>c__DisplayClass0_0.x""
  IL_000d:  ldc.i4.2
  IL_000e:  conv.u
  IL_000f:  localloc
  IL_0011:  dup
  IL_0012:  ldloc.0
  IL_0013:  ldftn      ""byte C.<>c__DisplayClass0_0.<Main>b__0()""
  IL_0019:  newobj     ""System.Func<byte>..ctor(object, System.IntPtr)""
  IL_001e:  callvirt   ""byte System.Func<byte>.Invoke()""
  IL_0023:  stind.i1
  IL_0024:  dup
  IL_0025:  ldc.i4.1
  IL_0026:  add
  IL_0027:  ldloc.0
  IL_0028:  ldfld      ""byte C.<>c__DisplayClass0_0.x""
  IL_002d:  stind.i1
  IL_002e:  ldc.i4.1
  IL_002f:  add
  IL_0030:  ldind.u1
  IL_0031:  call       ""void System.Console.Write(int)""
  IL_0036:  ret
}");
        }
 
        [Fact]
        public void TestElementThrow()
        {
            var text = @"
using System;
 
static unsafe class C
{
    static void Use(int* i) {}
    
    static int M() { return 0; }
 
    static void Main()
    {
        var p = stackalloc[] { M(), true ? throw null : M(), M() };
        Use(p);
    }
}
";
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                verify: Verification.Fails).VerifyIL("C.Main",
@"{
  // Code size       17 (0x11)
  .maxstack  4
  IL_0000:  ldc.i4.s   12
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  dup
  IL_0006:  call       ""int C.M()""
  IL_000b:  stind.i4
  IL_000c:  dup
  IL_000d:  ldc.i4.4
  IL_000e:  add
  IL_000f:  ldnull
  IL_0010:  throw
}");
        }
 
        [Fact]
        public void TestUnused()
        {
            var text = @"
using System;
 
static unsafe class C
{
    static byte Method(int i)
    {
        Console.Write(i);
        return 0;
    }
 
    static void Main()
    {
        var p = stackalloc[] { 42, Method(1), 42, Method(2) };
    }
}
";
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                expectedOutput: "12",
                verify: Verification.Passes).VerifyIL("C.Main",
@"{
  // Code size       19 (0x13)
  .maxstack  1
  IL_0000:  ldc.i4.s   16
  IL_0002:  conv.u
  IL_0003:  pop
  IL_0004:  ldc.i4.1
  IL_0005:  call       ""byte C.Method(int)""
  IL_000a:  pop
  IL_000b:  ldc.i4.2
  IL_000c:  call       ""byte C.Method(int)""
  IL_0011:  pop
  IL_0012:  ret
}");
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeDebugExe,
                expectedOutput: "12",
                verify: Verification.Fails).VerifyIL("C.Main",
@"{
  // Code size       44 (0x2c)
  .maxstack  4
  .locals init (int* V_0) //p
  IL_0000:  nop
  IL_0001:  ldc.i4.s   16
  IL_0003:  conv.u
  IL_0004:  localloc
  IL_0006:  dup
  IL_0007:  ldc.i4.s   42
  IL_0009:  stind.i4
  IL_000a:  dup
  IL_000b:  ldc.i4.4
  IL_000c:  add
  IL_000d:  ldc.i4.1
  IL_000e:  call       ""byte C.Method(int)""
  IL_0013:  stind.i4
  IL_0014:  dup
  IL_0015:  ldc.i4.2
  IL_0016:  conv.i
  IL_0017:  ldc.i4.4
  IL_0018:  mul
  IL_0019:  add
  IL_001a:  ldc.i4.s   42
  IL_001c:  stind.i4
  IL_001d:  dup
  IL_001e:  ldc.i4.3
  IL_001f:  conv.i
  IL_0020:  ldc.i4.4
  IL_0021:  mul
  IL_0022:  add
  IL_0023:  ldc.i4.2
  IL_0024:  call       ""byte C.Method(int)""
  IL_0029:  stind.i4
  IL_002a:  stloc.0
  IL_002b:  ret
}");
        }
 
        [Fact]
        public void TestEmpty()
        {
            var text = @"
using System;
 
static unsafe class C
{
    static void Use(int* p)
    {
    }
 
    static void Main()
    {
        var p = stackalloc int[] {};
        Use(p);
    }
}
";
            // PEVerify: [ : C::Main][mdToken=0x6000002][offset 0x00000002][found Native Int][expected unmanaged pointer] Unexpected type on the stack.
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                verify: Verification.FailsPEVerify).VerifyIL("C.Main",
@"{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldc.i4.0
  IL_0001:  conv.u
  IL_0002:  call       ""void C.Use(int*)""
  IL_0007:  ret
}");
        }
 
        [Fact]
        public void TestIdenticalBytes1()
        {
            var text = @"
using System;
 
static unsafe class C
{
    static void Print(byte* p)
    {
        for (int i = 0; i < 3; i++)
            Console.Write(p[i]);
    }
 
    static void Main()
    {
        byte* p = stackalloc byte[3] { 42, 42, 42 };
        Print(p);
    }
}
";
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                verify: Verification.Fails, expectedOutput: @"424242").VerifyIL("C.Main",
@"{
  // Code size       16 (0x10)
  .maxstack  4
  IL_0000:  ldc.i4.3
  IL_0001:  conv.u
  IL_0002:  localloc
  IL_0004:  dup
  IL_0005:  ldc.i4.s   42
  IL_0007:  ldc.i4.3
  IL_0008:  initblk
  IL_000a:  call       ""void C.Print(byte*)""
  IL_000f:  ret
}");
        }
 
        [Fact]
        public void TestIdenticalBytes2()
        {
            var text = @"
using System;
 
static unsafe class C
{
    static void Print(uint* p)
    {
        for (int i = 0; i < 3; i++)
            Console.Write(p[i].ToString(""x""));
    }
 
    static void Main()
    {
        var p = stackalloc[] { 0xffffffff, 0xffffffff, 0xffffffff };
        Print(p);
    }
}
";
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                verify: Verification.Fails, expectedOutput: @"ffffffffffffffffffffffff").VerifyIL("C.Main",
@"{
  // Code size       21 (0x15)
  .maxstack  4
  IL_0000:  ldc.i4.s   12
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  dup
  IL_0006:  ldc.i4     0xff
  IL_000b:  ldc.i4.s   12
  IL_000d:  initblk
  IL_000f:  call       ""void C.Print(uint*)""
  IL_0014:  ret
}");
        }
 
        [Fact]
        public void TestEnum()
        {
            var text = """
using System;
 
static unsafe class C
{
    static void Print(E* p)
    {
        for (int i = 0; i < 3; i++)
            Console.Write(p[i]);
    }
 
    static void Main()
    {
        var p1 = stackalloc[] { E.A, E.B, E.C };
        var p2 = stackalloc[] { E.D, E.D, E.D };
 
        Print(p1);
        Print(p2);
    }
 
    enum E : byte { A, B, C, D }
}
""";
            CompileAndVerify(text,
                options: TestOptions.UnsafeReleaseExe,
                verify: Verification.Fails, expectedOutput: @"ABCDDD").VerifyIL("C.Main",
"""
{
  // Code size       38 (0x26)
  .maxstack  4
  .locals init (C.E* V_0) //p1
  IL_0000:  ldc.i4.3
  IL_0001:  conv.u
  IL_0002:  localloc
  IL_0004:  dup
  IL_0005:  ldsflda    "<PrivateImplementationDetails>.__StaticArrayInitTypeSize=3 <PrivateImplementationDetails>.AE4B3280E56E2FAF83F414A6E3DABE9D5FBE18976544C05FED121ACCB85B53FC"
  IL_000a:  ldc.i4.3
  IL_000b:  unaligned. 1
  IL_000e:  cpblk
  IL_0010:  stloc.0
  IL_0011:  ldc.i4.3
  IL_0012:  conv.u
  IL_0013:  localloc
  IL_0015:  dup
  IL_0016:  ldc.i4.3
  IL_0017:  ldc.i4.3
  IL_0018:  initblk
  IL_001a:  ldloc.0
  IL_001b:  call       "void C.Print(C.E*)"
  IL_0020:  call       "void C.Print(C.E*)"
  IL_0025:  ret
}
""");
        }
        [Fact]
        public void TestMixedBlockInit()
        {
            var text = @"
using System;
 
static unsafe class C
{
    static void Print(byte* p)
    {
        for (int i = 0; i < 9; i++)
            Console.Write(p[i]);
    }
 
    static byte M()
    {
        return 9;
    }
 
    static void Main()
    {
        byte* p = stackalloc byte[9] { 1, 2, 3, 4, 5, 6, 7, 8, M() };
        Print(p);
    }
}
";
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                verify: Verification.Fails, expectedOutput: @"123456789").VerifyIL("C.Main",
@"{
  // Code size       33 (0x21)
  .maxstack  4
  IL_0000:  ldc.i4.s   9
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  dup
  IL_0006:  ldsflda    ""<PrivateImplementationDetails>.__StaticArrayInitTypeSize=9 <PrivateImplementationDetails>.5248358BD96335E3BA4BB5D100E25AD64FAF4ADA8E613568E449FF981304C025""
  IL_000b:  ldc.i4.s   9
  IL_000d:  unaligned. 1
  IL_0010:  cpblk
  IL_0012:  dup
  IL_0013:  ldc.i4.8
  IL_0014:  add
  IL_0015:  call       ""byte C.M()""
  IL_001a:  stind.i1
  IL_001b:  call       ""void C.Print(byte*)""
  IL_0020:  ret
}");
        }
 
        [Fact]
        public void TestElementInit()
        {
            var text = @"
using System;
 
struct S
{
    public int i;
}
 
static unsafe class C
{
    static void Print(S* p)
    {
        for (int i = 0; i < 3; i++)
            Console.Write(p[i].i);
    }
 
    static S M(int i)
    {
        return new S { i = i };
    }
    
    static void Main()
    {
        S* p = stackalloc S[3] { M(1), M(2), M(3) };
        Print(p);
    }
}
";
            CompileAndVerify(text,
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                verify: Verification.Fails, expectedOutput: @"123").VerifyIL("C.Main",
@"{
  // Code size       70 (0x46)
  .maxstack  4
  IL_0000:  ldc.i4.3
  IL_0001:  conv.u
  IL_0002:  sizeof     ""S""
  IL_0008:  mul.ovf.un
  IL_0009:  localloc
  IL_000b:  dup
  IL_000c:  ldc.i4.1
  IL_000d:  call       ""S C.M(int)""
  IL_0012:  stobj      ""S""
  IL_0017:  dup
  IL_0018:  sizeof     ""S""
  IL_001e:  add
  IL_001f:  ldc.i4.2
  IL_0020:  call       ""S C.M(int)""
  IL_0025:  stobj      ""S""
  IL_002a:  dup
  IL_002b:  ldc.i4.2
  IL_002c:  conv.i
  IL_002d:  sizeof     ""S""
  IL_0033:  mul
  IL_0034:  add
  IL_0035:  ldc.i4.3
  IL_0036:  call       ""S C.M(int)""
  IL_003b:  stobj      ""S""
  IL_0040:  call       ""void C.Print(S*)""
  IL_0045:  ret
}");
        }
 
        [Fact]
        public void TestBytePointer()
        {
            Test("System.Byte",
@"{
  // Code size       22 (0x16)
  .maxstack  4
  IL_0000:  ldc.i4.3
  IL_0001:  conv.u
  IL_0002:  localloc
  IL_0004:  dup
  IL_0005:  ldsflda    ""<PrivateImplementationDetails>.__StaticArrayInitTypeSize=3 <PrivateImplementationDetails>.039058C6F2C0CB492C533B0A4D14EF77CC0F78ABCCCED5287D84A1A2011CFB81""
  IL_000a:  ldc.i4.3
  IL_000b:  unaligned. 1
  IL_000e:  cpblk
  IL_0010:  call       ""void C.Print(byte*)""
  IL_0015:  ret
}");
        }
 
        [Fact]
        public void TestInt32Pointer()
        {
            Test("System.Int32",
@"{
  // Code size       27 (0x1b)
  .maxstack  4
  IL_0000:  ldc.i4.s   12
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  dup
  IL_0006:  ldc.i4.1
  IL_0007:  stind.i4
  IL_0008:  dup
  IL_0009:  ldc.i4.4
  IL_000a:  add
  IL_000b:  ldc.i4.2
  IL_000c:  stind.i4
  IL_000d:  dup
  IL_000e:  ldc.i4.2
  IL_000f:  conv.i
  IL_0010:  ldc.i4.4
  IL_0011:  mul
  IL_0012:  add
  IL_0013:  ldc.i4.3
  IL_0014:  stind.i4
  IL_0015:  call       ""void C.Print(int*)""
  IL_001a:  ret
}");
        }
 
        [Fact]
        public void TestInt64Pointer()
        {
            Test("System.Int64",
@"{
  // Code size       30 (0x1e)
  .maxstack  4
  IL_0000:  ldc.i4.s   24
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  dup
  IL_0006:  ldc.i4.1
  IL_0007:  conv.i8
  IL_0008:  stind.i8
  IL_0009:  dup
  IL_000a:  ldc.i4.8
  IL_000b:  add
  IL_000c:  ldc.i4.2
  IL_000d:  conv.i8
  IL_000e:  stind.i8
  IL_000f:  dup
  IL_0010:  ldc.i4.2
  IL_0011:  conv.i
  IL_0012:  ldc.i4.8
  IL_0013:  mul
  IL_0014:  add
  IL_0015:  ldc.i4.3
  IL_0016:  conv.i8
  IL_0017:  stind.i8
  IL_0018:  call       ""void C.Print(long*)""
  IL_001d:  ret
}");
        }
 
        [Fact]
        public void TestSpan()
        {
            var comp = CreateCompilation(@"
using System;
static class C
{
    static void Main()
    {
        Span<byte> p = stackalloc byte[3] { 1, 2, 3 };
    }
}
 
namespace System
{
    public ref struct Span<T> {
        public unsafe Span(void* p, int length)
        {
            for (int i = 0; i < 3; i++)
                Console.Write(((byte*)p)[i]);
        }
    }
}
", options: TestOptions.UnsafeReleaseExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3));
            CompileAndVerify(comp, verify: Verification.Fails, expectedOutput: @"123")
                .VerifyDiagnostics()
                .VerifyIL("C.Main",
@"
{
  // Code size       24 (0x18)
  .maxstack  4
  IL_0000:  ldc.i4.3
  IL_0001:  conv.u
  IL_0002:  localloc
  IL_0004:  dup
  IL_0005:  ldsflda    ""<PrivateImplementationDetails>.__StaticArrayInitTypeSize=3 <PrivateImplementationDetails>.039058C6F2C0CB492C533B0A4D14EF77CC0F78ABCCCED5287D84A1A2011CFB81""
  IL_000a:  ldc.i4.3
  IL_000b:  unaligned. 1
  IL_000e:  cpblk
  IL_0010:  ldc.i4.3
  IL_0011:  newobj     ""System.Span<byte>..ctor(void*, int)""
  IL_0016:  pop
  IL_0017:  ret
}
");
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestSpan_ZeroElements()
        {
            var source = """
                using System;
                static class C
                {
                    static void Main()
                    {
                        Span<byte> p = stackalloc byte[0];
                        Write(p);
                    }
 
                    static void Write(Span<byte> span)
                    {
                        foreach (byte x in span)
                            Console.Write(x);
                    }
                }
                """;
            var verifier = CompileAndVerify(source, expectedOutput: ExecutionConditionUtil.IsCoreClr ? "" : null,
                verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       15 (0xf)
                  .maxstack  1
                  .locals init (System.Span<byte> V_0)
                  IL_0000:  ldloca.s   V_0
                  IL_0002:  initobj    "System.Span<byte>"
                  IL_0008:  ldloc.0
                  IL_0009:  call       "void C.Write(System.Span<byte>)"
                  IL_000e:  ret
                }
                """);
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestSpanInt()
        {
            var source = """
                using System;
                static class C
                {
                    static void Main()
                    {
                        Span<int> p = stackalloc int[3] { 1, 2, 3 };
                        Write(p);
                    }
 
                    static void Write(Span<int> span)
                    {
                        foreach (int x in span)
                            Console.Write(x);
                    }
                }
                """;
            var expectedOutput = ExecutionConditionUtil.IsCoreClr ? "123" : null;
            var verifier = CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       44 (0x2c)
                  .maxstack  4
                  .locals init (System.ReadOnlySpan<int> V_0)
                  IL_0000:  ldc.i4.s   12
                  IL_0002:  conv.u
                  IL_0003:  localloc
                  IL_0005:  dup
                  IL_0006:  ldtoken    "<PrivateImplementationDetails>.__StaticArrayInitTypeSize=12_Align=4 <PrivateImplementationDetails>.4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D4"
                  IL_000b:  call       "System.ReadOnlySpan<int> System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan<int>(System.RuntimeFieldHandle)"
                  IL_0010:  stloc.0
                  IL_0011:  ldloca.s   V_0
                  IL_0013:  ldc.i4.0
                  IL_0014:  call       "ref readonly int System.ReadOnlySpan<int>.this[int].get"
                  IL_0019:  ldc.i4.s   12
                  IL_001b:  unaligned. 4
                  IL_001e:  cpblk
                  IL_0020:  ldc.i4.3
                  IL_0021:  newobj     "System.Span<int>..ctor(void*, int)"
                  IL_0026:  call       "void C.Write(System.Span<int>)"
                  IL_002b:  ret
                }
                """);
 
            CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70,
                options: TestOptions.DebugExe).VerifyDiagnostics();
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestSpanInt_ZeroElements()
        {
            var source = """
                using System;
                static class C
                {
                    static void Main()
                    {
                        Span<int> p = stackalloc int[0];
                        Write(p);
                    }
 
                    static void Write(Span<int> span)
                    {
                        foreach (int x in span)
                            Console.Write(x);
                    }
                }
                """;
            var verifier = CompileAndVerify(source, expectedOutput: ExecutionConditionUtil.IsCoreClr ? "" : null,
                verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       15 (0xf)
                  .maxstack  1
                  .locals init (System.Span<int> V_0)
                  IL_0000:  ldloca.s   V_0
                  IL_0002:  initobj    "System.Span<int>"
                  IL_0008:  ldloc.0
                  IL_0009:  call       "void C.Write(System.Span<int>)"
                  IL_000e:  ret
                }
                """);
        }
 
        [Fact]
        public void TestReadOnlySpan()
        {
            var comp = CreateCompilation(@"
using System;
static class C
{
    static void Main()
    {
        ReadOnlySpan<int> p = stackalloc int[3] { 1, 2, 3 };
    }
}
 
namespace System
{
    public ref struct Span<T>
    {
        public unsafe Span(void* p, int length)
        {
            for (int i = 0; i < 3; i++)
                Console.Write(((int*)p)[i]);
        }
    }
 
    public readonly ref struct ReadOnlySpan<T>
    {
        public static implicit operator System.ReadOnlySpan<T> (System.Span<T> span) => default;
    }
}
", options: TestOptions.UnsafeReleaseExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3));
            CompileAndVerify(comp, verify: Verification.Fails, expectedOutput: @"123")
                .VerifyDiagnostics()
                .VerifyIL("C.Main",
@"
{
  // Code size       34 (0x22)
  .maxstack  4
  IL_0000:  ldc.i4.s   12
  IL_0002:  conv.u
  IL_0003:  localloc
  IL_0005:  dup
  IL_0006:  ldc.i4.1
  IL_0007:  stind.i4
  IL_0008:  dup
  IL_0009:  ldc.i4.4
  IL_000a:  add
  IL_000b:  ldc.i4.2
  IL_000c:  stind.i4
  IL_000d:  dup
  IL_000e:  ldc.i4.2
  IL_000f:  conv.i
  IL_0010:  ldc.i4.4
  IL_0011:  mul
  IL_0012:  add
  IL_0013:  ldc.i4.3
  IL_0014:  stind.i4
  IL_0015:  ldc.i4.3
  IL_0016:  newobj     ""System.Span<int>..ctor(void*, int)""
  IL_001b:  call       ""System.ReadOnlySpan<int> System.ReadOnlySpan<int>.op_Implicit(System.Span<int>)""
  IL_0020:  pop
  IL_0021:  ret
}
");
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestReadOnlySpan_Net7()
        {
            var source = """
                using System;
                static class C
                {
                    static void Main()
                    {
                        ReadOnlySpan<int> p = stackalloc int[3] { 1, 2, 3 };
                        Write(p);
                    }
 
                    static void Write(ReadOnlySpan<int> span)
                    {
                        foreach (int x in span)
                            Console.Write(x);
                    }
                }
                """;
            var expectedOutput = ExecutionConditionUtil.IsCoreClr ? "123" : null;
            var verifier = CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       49 (0x31)
                  .maxstack  4
                  .locals init (System.ReadOnlySpan<int> V_0)
                  IL_0000:  ldc.i4.s   12
                  IL_0002:  conv.u
                  IL_0003:  localloc
                  IL_0005:  dup
                  IL_0006:  ldtoken    "<PrivateImplementationDetails>.__StaticArrayInitTypeSize=12_Align=4 <PrivateImplementationDetails>.4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D4"
                  IL_000b:  call       "System.ReadOnlySpan<int> System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan<int>(System.RuntimeFieldHandle)"
                  IL_0010:  stloc.0
                  IL_0011:  ldloca.s   V_0
                  IL_0013:  ldc.i4.0
                  IL_0014:  call       "ref readonly int System.ReadOnlySpan<int>.this[int].get"
                  IL_0019:  ldc.i4.s   12
                  IL_001b:  unaligned. 4
                  IL_001e:  cpblk
                  IL_0020:  ldc.i4.3
                  IL_0021:  newobj     "System.Span<int>..ctor(void*, int)"
                  IL_0026:  call       "System.ReadOnlySpan<int> System.Span<int>.op_Implicit(System.Span<int>)"
                  IL_002b:  call       "void C.Write(System.ReadOnlySpan<int>)"
                  IL_0030:  ret
                }
                """);
 
            CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70,
                options: TestOptions.DebugExe).VerifyDiagnostics();
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestReadOnlySpan_Net7_Byte()
        {
            var source = """
                using System;
                static class C
                {
                    static void Main()
                    {
                        ReadOnlySpan<byte> p = stackalloc byte[3] { 1, 2, 3 };
                        Write(p);
                    }
 
                    static void Write(ReadOnlySpan<byte> span)
                    {
                        foreach (byte x in span)
                            Console.Write(x);
                    }
                }
                """;
            var verifier = CompileAndVerify(source, expectedOutput: ExecutionConditionUtil.IsCoreClr ? "123" : null,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       33 (0x21)
                  .maxstack  4
                  IL_0000:  ldc.i4.3
                  IL_0001:  conv.u
                  IL_0002:  localloc
                  IL_0004:  dup
                  IL_0005:  ldsflda    "<PrivateImplementationDetails>.__StaticArrayInitTypeSize=3 <PrivateImplementationDetails>.039058C6F2C0CB492C533B0A4D14EF77CC0F78ABCCCED5287D84A1A2011CFB81"
                  IL_000a:  ldc.i4.3
                  IL_000b:  unaligned. 1
                  IL_000e:  cpblk
                  IL_0010:  ldc.i4.3
                  IL_0011:  newobj     "System.Span<byte>..ctor(void*, int)"
                  IL_0016:  call       "System.ReadOnlySpan<byte> System.Span<byte>.op_Implicit(System.Span<byte>)"
                  IL_001b:  call       "void C.Write(System.ReadOnlySpan<byte>)"
                  IL_0020:  ret
                }
                """);
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestReadOnlySpan_Net7_Short()
        {
            var source = """
                using System;
                static class C
                {
                    static void Main()
                    {
                        ReadOnlySpan<short> p = stackalloc short[3] { 1, 2, 3 };
                        Write(p);
                    }
 
                    static void Write(ReadOnlySpan<short> span)
                    {
                        foreach (short x in span)
                            Console.Write(x);
                    }
                }
                """;
            var expectedOutput = ExecutionConditionUtil.IsCoreClr ? "123" : null;
            var verifier = CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       47 (0x2f)
                  .maxstack  4
                  .locals init (System.ReadOnlySpan<short> V_0)
                  IL_0000:  ldc.i4.6
                  IL_0001:  conv.u
                  IL_0002:  localloc
                  IL_0004:  dup
                  IL_0005:  ldtoken    "<PrivateImplementationDetails>.__StaticArrayInitTypeSize=6_Align=2 <PrivateImplementationDetails>.047DBF5366372631BA7E3E02520E651446B899C96C4B64663BAC378A298A7BF72"
                  IL_000a:  call       "System.ReadOnlySpan<short> System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan<short>(System.RuntimeFieldHandle)"
                  IL_000f:  stloc.0
                  IL_0010:  ldloca.s   V_0
                  IL_0012:  ldc.i4.0
                  IL_0013:  call       "ref readonly short System.ReadOnlySpan<short>.this[int].get"
                  IL_0018:  ldc.i4.6
                  IL_0019:  unaligned. 2
                  IL_001c:  cpblk
                  IL_001e:  ldc.i4.3
                  IL_001f:  newobj     "System.Span<short>..ctor(void*, int)"
                  IL_0024:  call       "System.ReadOnlySpan<short> System.Span<short>.op_Implicit(System.Span<short>)"
                  IL_0029:  call       "void C.Write(System.ReadOnlySpan<short>)"
                  IL_002e:  ret
                }
                """);
 
            CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70,
                options: TestOptions.DebugExe).VerifyDiagnostics();
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestReadOnlySpan_Net7_Double()
        {
            var source = """
                using System;
                using System.Globalization;
 
                static class C
                {
                    static void Main()
                    {
                        ReadOnlySpan<double> p = stackalloc double[3] { 1.0, 2.9, 3.8 };
                        Write(p);
                    }
 
                    static void Write(ReadOnlySpan<double> span)
                    {
                        foreach (double x in span)
                            Console.Write(x.ToString(CultureInfo.InvariantCulture) + " ");
                    }
                }
                """;
            var expectedOutput = ExecutionConditionUtil.IsCoreClr ? "1 2.9 3.8" : null;
            var verifier = CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       46 (0x2e)
                  .maxstack  4
                  .locals init (System.ReadOnlySpan<double> V_0)
                  IL_0000:  ldc.i4.s   24
                  IL_0002:  conv.u
                  IL_0003:  localloc
                  IL_0005:  dup
                  IL_0006:  ldtoken    "<PrivateImplementationDetails>.__StaticArrayInitTypeSize=24_Align=8 <PrivateImplementationDetails>.A469E23C2EF824690D849F86F0B660CC6E91A9E4BE44208A7103F98510BF64F58"
                  IL_000b:  call       "System.ReadOnlySpan<double> System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan<double>(System.RuntimeFieldHandle)"
                  IL_0010:  stloc.0
                  IL_0011:  ldloca.s   V_0
                  IL_0013:  ldc.i4.0
                  IL_0014:  call       "ref readonly double System.ReadOnlySpan<double>.this[int].get"
                  IL_0019:  ldc.i4.s   24
                  IL_001b:  cpblk
                  IL_001d:  ldc.i4.3
                  IL_001e:  newobj     "System.Span<double>..ctor(void*, int)"
                  IL_0023:  call       "System.ReadOnlySpan<double> System.Span<double>.op_Implicit(System.Span<double>)"
                  IL_0028:  call       "void C.Write(System.ReadOnlySpan<double>)"
                  IL_002d:  ret
                }
                """);
 
            CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70,
                options: TestOptions.DebugExe).VerifyDiagnostics();
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestReadOnlySpan_Net7_Enum()
        {
            var source = """
                using System;
                enum E : long { X, Y, Z }
                static class C
                {
                    static void Main()
                    {
                        ReadOnlySpan<E> p = stackalloc E[3] { E.X, E.Y, E.Z };
                        Write(p);
                    }
 
                    static void Write(ReadOnlySpan<E> span)
                    {
                        foreach (E x in span)
                            Console.Write(x);
                    }
                }
                """;
            var expectedOutput = ExecutionConditionUtil.IsCoreClr ? "XYZ" : null;
            var verifier = CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       46 (0x2e)
                  .maxstack  4
                  .locals init (System.ReadOnlySpan<E> V_0)
                  IL_0000:  ldc.i4.s   24
                  IL_0002:  conv.u
                  IL_0003:  localloc
                  IL_0005:  dup
                  IL_0006:  ldtoken    "<PrivateImplementationDetails>.__StaticArrayInitTypeSize=24_Align=8 <PrivateImplementationDetails>.AB25350E3E65EFEBE24584461683ECDA68725576E825E550038B90E7B14799468"
                  IL_000b:  call       "System.ReadOnlySpan<E> System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan<E>(System.RuntimeFieldHandle)"
                  IL_0010:  stloc.0
                  IL_0011:  ldloca.s   V_0
                  IL_0013:  ldc.i4.0
                  IL_0014:  call       "ref readonly E System.ReadOnlySpan<E>.this[int].get"
                  IL_0019:  ldc.i4.s   24
                  IL_001b:  cpblk
                  IL_001d:  ldc.i4.3
                  IL_001e:  newobj     "System.Span<E>..ctor(void*, int)"
                  IL_0023:  call       "System.ReadOnlySpan<E> System.Span<E>.op_Implicit(System.Span<E>)"
                  IL_0028:  call       "void C.Write(System.ReadOnlySpan<E>)"
                  IL_002d:  ret
                }
                """);
 
            CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70,
                options: TestOptions.DebugExe).VerifyDiagnostics();
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestReadOnlySpan_Net7_FewElements()
        {
            var source = """
                using System;
                static class C
                {
                    static void Main()
                    {
                        ReadOnlySpan<int> p = stackalloc int[] { 1, 2 };
                        Write(p);
                    }
 
                    static void Write(ReadOnlySpan<int> span)
                    {
                        foreach (int x in span)
                            Console.Write(x);
                    }
                }
                """;
            var verifier = CompileAndVerify(source, expectedOutput: ExecutionConditionUtil.IsCoreClr ? "12" : null,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       29 (0x1d)
                  .maxstack  3
                  IL_0000:  ldc.i4.8
                  IL_0001:  conv.u
                  IL_0002:  localloc
                  IL_0004:  dup
                  IL_0005:  ldc.i4.1
                  IL_0006:  stind.i4
                  IL_0007:  dup
                  IL_0008:  ldc.i4.4
                  IL_0009:  add
                  IL_000a:  ldc.i4.2
                  IL_000b:  stind.i4
                  IL_000c:  ldc.i4.2
                  IL_000d:  newobj     "System.Span<int>..ctor(void*, int)"
                  IL_0012:  call       "System.ReadOnlySpan<int> System.Span<int>.op_Implicit(System.Span<int>)"
                  IL_0017:  call       "void C.Write(System.ReadOnlySpan<int>)"
                  IL_001c:  ret
                }
                """);
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestReadOnlySpan_ZeroElements_Byte()
        {
            var source = """
                using System;
                static class C
                {
                    static void Main()
                    {
                        ReadOnlySpan<byte> p = stackalloc byte[0];
                        Write(p);
                    }
 
                    static void Write(ReadOnlySpan<byte> span)
                    {
                        foreach (byte x in span)
                            Console.Write(x);
                    }
                }
                """;
            var verifier = CompileAndVerify(source, expectedOutput: ExecutionConditionUtil.IsCoreClr ? "" : null,
                verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       20 (0x14)
                  .maxstack  1
                  .locals init (System.Span<byte> V_0)
                  IL_0000:  ldloca.s   V_0
                  IL_0002:  initobj    "System.Span<byte>"
                  IL_0008:  ldloc.0
                  IL_0009:  call       "System.ReadOnlySpan<byte> System.Span<byte>.op_Implicit(System.Span<byte>)"
                  IL_000e:  call       "void C.Write(System.ReadOnlySpan<byte>)"
                  IL_0013:  ret
                }
                """);
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestReadOnlySpan_ZeroElements_Int()
        {
            var source = """
                using System;
                static class C
                {
                    static void Main()
                    {
                        ReadOnlySpan<int> p = stackalloc int[0];
                        Write(p);
                    }
 
                    static void Write(ReadOnlySpan<int> span)
                    {
                        foreach (int x in span)
                            Console.Write(x);
                    }
                }
                """;
            var verifier = CompileAndVerify(source, expectedOutput: ExecutionConditionUtil.IsCoreClr ? "" : null,
                verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       20 (0x14)
                  .maxstack  1
                  .locals init (System.Span<int> V_0)
                  IL_0000:  ldloca.s   V_0
                  IL_0002:  initobj    "System.Span<int>"
                  IL_0008:  ldloc.0
                  IL_0009:  call       "System.ReadOnlySpan<int> System.Span<int>.op_Implicit(System.Span<int>)"
                  IL_000e:  call       "void C.Write(System.ReadOnlySpan<int>)"
                  IL_0013:  ret
                }
                """);
        }
 
        [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        [InlineData((int)WellKnownMember.System_Runtime_CompilerServices_RuntimeHelpers__CreateSpanRuntimeFieldHandle)]
        [InlineData((int)WellKnownMember.System_ReadOnlySpan_T__get_Item)]
        public void TestPointerCreateSpan(int missingMember)
        {
            var source = """
                using System;
                unsafe static class C
                {
                    static void Main()
                    {
                        int* p = stackalloc int[3] { 1, 2, 3 };
                        Write(p);
                    }
 
                    static void Write(int* span)
                    {
                        for (int i = 0; i < 3; i++)
                            Console.Write(span[i]);
                    }
                }
                """;
            var output = "123";
            var verifier = CompileAndVerify(source, expectedOutput: ExecutionConditionUtil.IsCoreClr ? output : null,
                verify: Verification.Fails, options: TestOptions.UnsafeReleaseExe, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       38 (0x26)
                  .maxstack  4
                  .locals init (System.ReadOnlySpan<int> V_0)
                  IL_0000:  ldc.i4.s   12
                  IL_0002:  conv.u
                  IL_0003:  localloc
                  IL_0005:  dup
                  IL_0006:  ldtoken    "<PrivateImplementationDetails>.__StaticArrayInitTypeSize=12_Align=4 <PrivateImplementationDetails>.4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D4"
                  IL_000b:  call       "System.ReadOnlySpan<int> System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan<int>(System.RuntimeFieldHandle)"
                  IL_0010:  stloc.0
                  IL_0011:  ldloca.s   V_0
                  IL_0013:  ldc.i4.0
                  IL_0014:  call       "ref readonly int System.ReadOnlySpan<int>.this[int].get"
                  IL_0019:  ldc.i4.s   12
                  IL_001b:  unaligned. 4
                  IL_001e:  cpblk
                  IL_0020:  call       "void C.Write(int*)"
                  IL_0025:  ret
                }
                """);
 
            CompileAndVerify(source, expectedOutput: ExecutionConditionUtil.IsCoreClr ? output : null,
                verify: Verification.Fails, options: TestOptions.UnsafeDebugExe, targetFramework: TargetFramework.Net70).VerifyDiagnostics();
 
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseExe, targetFramework: TargetFramework.Net70);
            comp.MakeMemberMissing((WellKnownMember)missingMember);
            verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsCoreClr ? output : null, verify: Verification.Fails);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       27 (0x1b)
                  .maxstack  4
                  IL_0000:  ldc.i4.s   12
                  IL_0002:  conv.u
                  IL_0003:  localloc
                  IL_0005:  dup
                  IL_0006:  ldc.i4.1
                  IL_0007:  stind.i4
                  IL_0008:  dup
                  IL_0009:  ldc.i4.4
                  IL_000a:  add
                  IL_000b:  ldc.i4.2
                  IL_000c:  stind.i4
                  IL_000d:  dup
                  IL_000e:  ldc.i4.2
                  IL_000f:  conv.i
                  IL_0010:  ldc.i4.4
                  IL_0011:  mul
                  IL_0012:  add
                  IL_0013:  ldc.i4.3
                  IL_0014:  stind.i4
                  IL_0015:  call       "void C.Write(int*)"
                  IL_001a:  ret
                }
                """);
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestPointerCreateSpan_NonBlittableType()
        {
            var source = """
                using System;
                unsafe static class C
                {
                    static void Main()
                    {
                        decimal* p = stackalloc decimal[3] { 1m, 2m, 3m };
                        Write(p);
                    }
 
                    static void Write(decimal* span)
                    {
                        for (int i = 0; i < 3; i++)
                            Console.Write(span[i]);
                    }
                }
                """;
            var verifier = CompileAndVerify(source, expectedOutput: ExecutionConditionUtil.IsCoreClr ? "123" : null,
                verify: Verification.Fails, options: TestOptions.UnsafeReleaseExe, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.Main", """
                {
                  // Code size       55 (0x37)
                  .maxstack  4
                  IL_0000:  ldc.i4.s   48
                  IL_0002:  conv.u
                  IL_0003:  localloc
                  IL_0005:  dup
                  IL_0006:  ldsfld     "decimal decimal.One"
                  IL_000b:  stobj      "decimal"
                  IL_0010:  dup
                  IL_0011:  ldc.i4.s   16
                  IL_0013:  add
                  IL_0014:  ldc.i4.2
                  IL_0015:  newobj     "decimal..ctor(int)"
                  IL_001a:  stobj      "decimal"
                  IL_001f:  dup
                  IL_0020:  ldc.i4.2
                  IL_0021:  conv.i
                  IL_0022:  ldc.i4.s   16
                  IL_0024:  mul
                  IL_0025:  add
                  IL_0026:  ldc.i4.3
                  IL_0027:  newobj     "decimal..ctor(int)"
                  IL_002c:  stobj      "decimal"
                  IL_0031:  call       "void C.Write(decimal*)"
                  IL_0036:  ret
                }
                """);
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69325")]
        public void TestMixed()
        {
            var source = """
                using System;
                static class C
                {
                    static void Main() => M(4);
 
                    static void M(int i)
                    {
                        ReadOnlySpan<int> p = stackalloc int[] { 1, 2, 3, i };
                        Write(p);
                    }
 
                    static void Write(ReadOnlySpan<int> span)
                    {
                        foreach (int x in span)
                            Console.Write(x);
                    }
                }
                """;
            var expectedOutput = ExecutionConditionUtil.IsCoreClr ? "1234" : null;
            var verifier = CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70);
            verifier.VerifyDiagnostics();
            verifier.VerifyIL("C.M", """
                {
                  // Code size       57 (0x39)
                  .maxstack  4
                  .locals init (System.ReadOnlySpan<int> V_0)
                  IL_0000:  ldc.i4.s   16
                  IL_0002:  conv.u
                  IL_0003:  localloc
                  IL_0005:  dup
                  IL_0006:  ldtoken    "<PrivateImplementationDetails>.__StaticArrayInitTypeSize=16_Align=4 <PrivateImplementationDetails>.81C1A5A2F482E82CA2C66653482AB24E6D90944BF183C8164E8F8F8D72DB60DB4"
                  IL_000b:  call       "System.ReadOnlySpan<int> System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan<int>(System.RuntimeFieldHandle)"
                  IL_0010:  stloc.0
                  IL_0011:  ldloca.s   V_0
                  IL_0013:  ldc.i4.0
                  IL_0014:  call       "ref readonly int System.ReadOnlySpan<int>.this[int].get"
                  IL_0019:  ldc.i4.s   16
                  IL_001b:  unaligned. 4
                  IL_001e:  cpblk
                  IL_0020:  dup
                  IL_0021:  ldc.i4.3
                  IL_0022:  conv.i
                  IL_0023:  ldc.i4.4
                  IL_0024:  mul
                  IL_0025:  add
                  IL_0026:  ldarg.0
                  IL_0027:  stind.i4
                  IL_0028:  ldc.i4.4
                  IL_0029:  newobj     "System.Span<int>..ctor(void*, int)"
                  IL_002e:  call       "System.ReadOnlySpan<int> System.Span<int>.op_Implicit(System.Span<int>)"
                  IL_0033:  call       "void C.Write(System.ReadOnlySpan<int>)"
                  IL_0038:  ret
                }
                """);
 
            CompileAndVerify(source, expectedOutput: expectedOutput,
                verify: Verification.Fails, targetFramework: TargetFramework.Net70,
                options: TestOptions.DebugExe).VerifyDiagnostics();
        }
 
        private static string GetSource(string pointerType) => $@"
using System;
using T = {pointerType};
static unsafe class C
{{
    static void Print(T* p)
    {{
        for (int i = 0; i < 3; i++)
            Console.Write(p[i]);
    }}
 
    static void Main()
    {{
        T* p = stackalloc T[3] {{ 1, 2, 3 }};
        Print(p);
    }}
}}
";
 
        private void Test(string pointerType, string il)
            => CompileAndVerify(GetSource(pointerType),
                parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
                options: TestOptions.UnsafeReleaseExe,
                verify: Verification.Fails,
                expectedOutput: @"123").VerifyIL("C.Main", il);
    }
}