File: UnsafeEvolutionTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\CSharp15\Microsoft.CodeAnalysis.CSharp.CSharp15.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.CSharp15.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.
 
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics;
 
[CompilerTrait(CompilerFeature.Unsafe)]
public sealed class UnsafeEvolutionTests : CompilingTestBase
{
    /// <param name="expectedUnsafeSymbols">See <see cref="VerifyRequiresUnsafeAttribute"/>.</param>
    /// <param name="expectedSafeSymbols">See <see cref="VerifyRequiresUnsafeAttribute"/>.</param>
    private void CompileAndVerifyUnsafe(
        string lib,
        string caller,
        object[] expectedUnsafeSymbols,
        object[] expectedSafeSymbols,
        DiagnosticDescription[] expectedDiagnostics,
        ReadOnlySpan<string> additionalSources = default,
        Verification verify = default,
        CallerUnsafeMode expectedUnsafeMode = CallerUnsafeMode.Explicit,
        object[]? expectedNoAttributeInSource = null,
        object[]? expectedNoAttributeUnderLegacyRules = null,
        object[]? skipSymbolsInSource = null,
        CSharpParseOptions? parseOptions = null,
        CSharpCompilationOptions? optionsDll = null,
        TargetFramework targetFramework = TargetFramework.Standard,
        DiagnosticDescription[]? expectedDiagnosticsWhenReferencingLegacyLib = null,
        DiagnosticDescription[]? expectedDiagnosticsForLegacyCaller = null)
    {
        optionsDll ??= TestOptions.UnsafeReleaseDll;
        var optionsExe = optionsDll.WithOutputKind(OutputKind.ConsoleApplication);
 
        Assert.False(optionsDll.UseUpdatedMemorySafetyRules);
 
        CreateCompilation([lib, caller, .. additionalSources],
            targetFramework: targetFramework,
            parseOptions: parseOptions,
            options: optionsExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        var libUpdated = CompileAndVerify([lib, .. additionalSources],
            targetFramework: targetFramework,
            parseOptions: parseOptions,
            options: optionsDll.WithUpdatedMemorySafetyRules(),
            verify: verify,
            symbolValidator: symbolValidator)
            .VerifyDiagnostics();
 
        var libUpdatedRefs = new MetadataReference[] { libUpdated.GetImageReference(), libUpdated.Compilation.ToMetadataReference() };
 
        foreach (var libUpdatedRef in libUpdatedRefs)
        {
            var libAssemblySymbol = CreateCompilation(caller, [libUpdatedRef],
                targetFramework: targetFramework,
                parseOptions: parseOptions,
                options: optionsExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(expectedDiagnostics)
                .GetReferencedAssemblySymbol(libUpdatedRef);
 
            symbolValidator(libAssemblySymbol.Modules.Single());
 
            // Updated-rules library referenced by legacy-rules caller.
            CreateCompilation(caller, [libUpdatedRef],
                targetFramework: targetFramework,
                parseOptions: parseOptions,
                options: optionsExe.AddSpecificDiagnosticOptions(GetIdForErrorCode(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules), ReportDiagnostic.Suppress))
                .VerifyDiagnostics(expectedDiagnosticsForLegacyCaller ?? []);
        }
 
        var libLegacy = CompileAndVerify([lib, .. additionalSources],
            targetFramework: targetFramework,
            parseOptions: parseOptions,
            options: optionsDll.AddSpecificDiagnosticOptions(GetIdForErrorCode(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules), ReportDiagnostic.Suppress),
            verify: verify,
            symbolValidator: module =>
            {
                VerifyMemorySafetyRulesAttribute(module, includesAttributeDefinition: false, includesAttributeUse: false);
                VerifyRequiresUnsafeAttribute(
                    module,
                    expectedUnsafeSymbols: expectedUnsafeSymbols,
                    expectedSafeSymbols: expectedSafeSymbols,
                    expectedNoAttributeInSource: expectedNoAttributeInSource,
                    expectedNoAttribute: expectedNoAttributeUnderLegacyRules,
                    expectedUnsafeMode: CallerUnsafeMode.None);
            })
            .VerifyDiagnostics()
            .GetImageReference();
 
        CreateCompilation(caller, [libLegacy],
            targetFramework: targetFramework,
            parseOptions: parseOptions,
            options: optionsExe.WithUpdatedMemorySafetyRules())
            .VerifyEmitDiagnostics(expectedDiagnosticsWhenReferencingLegacyLib ?? []);
 
        // Legacy-rules library referenced by legacy-rules caller.
        CreateCompilation(caller, [libLegacy],
            targetFramework: targetFramework,
            parseOptions: parseOptions,
            options: optionsExe.AddSpecificDiagnosticOptions(GetIdForErrorCode(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules), ReportDiagnostic.Suppress))
            .VerifyEmitDiagnostics(expectedDiagnosticsForLegacyCaller ?? []);
 
        void symbolValidator(ModuleSymbol module)
        {
            var isSource = module is SourceModuleSymbol;
            VerifyMemorySafetyRulesAttribute(
                module,
                includesAttributeDefinition: !isSource,
                includesAttributeUse: !isSource,
                isSynthesized: isSource ? null : true);
            VerifyRequiresUnsafeAttribute(
                module,
                expectedUnsafeSymbols: exceptSymbolsSkippedInSource(expectedUnsafeSymbols),
                expectedSafeSymbols: exceptSymbolsSkippedInSource(expectedSafeSymbols),
                expectedNoAttributeInSource: exceptSymbolsSkippedInSource(expectedNoAttributeInSource),
                expectedUnsafeMode: expectedUnsafeMode);
 
            [return: NotNullIfNotNull(nameof(original))]
            object[]? exceptSymbolsSkippedInSource(object[]? original)
            {
                return isSource && skipSymbolsInSource is [..] && original is [..]
                    ? original.Except(skipSymbolsInSource).ToArray()
                    : original;
            }
        }
    }
 
    private static Func<ModuleSymbol, Symbol> ExtensionMember(string containerName, string memberName)
    {
        return module => module.GlobalNamespace
            .GetMember<NamedTypeSymbol>(containerName)
            .GetMembers("")
            .Cast<NamedTypeSymbol>()
            .SelectMany(block => block.GetMembers(memberName))
            .SingleOrDefault()
            ?? throw new InvalidOperationException($"Cannot find '{containerName}.{memberName}'.");
    }
 
    private static Func<ModuleSymbol, Symbol> Overload(string qualifiedName, int parameterCount)
    {
        return module => module.GlobalNamespace
            .GetMembersByQualifiedName<MethodSymbol>(qualifiedName)
            .SingleOrDefault(m => m.Parameters.Length == parameterCount)
            ?? throw new InvalidOperationException($"Cannot find '{qualifiedName}' with {parameterCount} parameters.");
    }
 
    private static Func<ModuleSymbol, Symbol> OverloadByReturnType(string qualifiedName, string returnType)
    {
        return module =>
        {
            var candidates = module.GlobalNamespace
                .GetMembersByQualifiedName<MethodSymbol>(qualifiedName);
 
            return candidates.SingleOrDefault(m => m.ReturnType.ToTestDisplayString() == returnType)
                ?? throw new InvalidOperationException($"Cannot find '{qualifiedName}' with return type '{returnType}'. " +
                    $"Found {string.Join(", ", candidates.Select(static m => m.ReturnType.ToTestDisplayString()))}.");
        };
    }
 
    private static void VerifyMemorySafetyRulesAttribute(
        ModuleSymbol module,
        bool includesAttributeDefinition,
        bool includesAttributeUse,
        bool? isSynthesized = null)
    {
        const string Name = "MemorySafetyRulesAttribute";
        const string FullName = $"System.Runtime.CompilerServices.{Name}";
        var type = (NamedTypeSymbol)module.GlobalNamespace.GetMember(FullName);
        var attribute = module.GetAttributes().SingleOrDefault(a => a.AttributeClass?.Name == Name);
 
        if (includesAttributeDefinition)
        {
            Assert.NotNull(type);
 
            Assert.NotNull(isSynthesized);
            if (isSynthesized.Value)
            {
                var attributeAttributes = type.GetAttributes()
                    .Select(a => a.AttributeClass.ToTestDisplayString())
                    .OrderBy(StringComparer.Ordinal);
                Assert.Equal(
                    [
                        "Microsoft.CodeAnalysis.EmbeddedAttribute",
                        "System.AttributeUsageAttribute",
                        "System.Runtime.CompilerServices.CompilerGeneratedAttribute",
                    ],
                    attributeAttributes);
            }
        }
        else
        {
            Assert.Null(type);
            if (includesAttributeUse)
            {
                Assert.NotNull(attribute);
                type = attribute.AttributeClass;
            }
        }
 
        if (type is { })
        {
            Assert.NotNull(isSynthesized);
            Assert.Equal(isSynthesized.Value ? Accessibility.Internal : Accessibility.Public, type.DeclaredAccessibility);
        }
        else
        {
            Assert.Null(isSynthesized);
        }
 
        if (includesAttributeUse)
        {
            Assert.NotNull(attribute);
            Assert.Equal(type, attribute.AttributeClass);
            Assert.Equal([2], attribute.ConstructorArguments.Select(a => a.Value));
            Assert.Equal([], attribute.NamedArguments);
        }
        else
        {
            Assert.Null(attribute);
        }
    }
 
    /// <remarks>
    /// <paramref name="expectedUnsafeSymbols"/> (and <paramref name="expectedSafeSymbols"/>) should be symbol names (<see cref="string"/>)
    /// or symbol getters (<c><![CDATA[Func<ModuleSymbol, Symbol>]]></c>) of symbols that are expected to be unsafe (or safe, respectively).
    /// </remarks>
    private static void VerifyRequiresUnsafeAttribute(
        ModuleSymbol module,
        ReadOnlySpan<object> expectedUnsafeSymbols,
        ReadOnlySpan<object> expectedSafeSymbols,
        object[]? expectedNoAttributeInSource = null,
        object[]? expectedNoAttribute = null,
        object[]? expectedAttribute = null,
        CallerUnsafeMode expectedUnsafeMode = CallerUnsafeMode.Explicit)
    {
        const string Name = "RequiresUnsafeAttribute";
 
        var expectedNoAttributeInSourceSymbols = (expectedNoAttributeInSource ?? []).SelectAsArray(getSymbol);
        var expectedNoAttributeSymbols = (expectedNoAttribute ?? []).SelectAsArray(getSymbol);
        var expectedAttributeSymbols = (expectedAttribute ?? []).SelectAsArray(getSymbol);
 
        var seenSymbols = new HashSet<Symbol>();
 
        foreach (var symbol in expectedUnsafeSymbols)
        {
            verifySymbol(symbol, shouldBeUnsafe: true);
        }
 
        foreach (var symbol in expectedSafeSymbols)
        {
            verifySymbol(symbol, shouldBeUnsafe: false);
        }
 
        Assert.All(expectedNoAttributeInSourceSymbols, s => Assert.True(seenSymbols.Contains(s)));
        Assert.All(expectedNoAttributeSymbols, s => Assert.True(seenSymbols.Contains(s)));
        Assert.All(expectedAttributeSymbols, s => Assert.True(seenSymbols.Contains(s)));
 
        void verifySymbol(object symbolGetter, bool shouldBeUnsafe)
        {
            var symbol = getSymbol(symbolGetter);
 
            var symbolExpectedUnsafeMode = shouldBeUnsafe ? expectedUnsafeMode : CallerUnsafeMode.None;
            Assert.True(symbolExpectedUnsafeMode == symbol.CallerUnsafeMode, $"Expected {symbol.GetType().Name} '{symbol.ToTestDisplayString()}' to have {nameof(CallerUnsafeMode)}.{symbolExpectedUnsafeMode} (got {symbol.CallerUnsafeMode}).");
 
            var attribute = symbol.GetAttributes().SingleOrDefault(a => a.AttributeClass?.Name == Name);
            var associatedAttribute = (symbol as MethodSymbol)?.AssociatedSymbol?.GetAttributes().SingleOrDefault(a => a.AttributeClass?.Name == Name);
            var hasAttribute = attribute is not null || associatedAttribute is not null;
            var shouldHaveAttribute = expectedAttributeSymbols.Contains(symbol) ||
                (shouldBeUnsafe && expectedUnsafeMode != CallerUnsafeMode.Implicit &&
                (module is not SourceModuleSymbol || !expectedNoAttributeInSourceSymbols.Contains(symbol)) &&
                !expectedNoAttributeSymbols.Contains(symbol));
            Assert.True(shouldHaveAttribute == hasAttribute,
                $"{(shouldHaveAttribute ? "Expected" : "Did not expect")} {symbol.GetType().Name} '{symbol.ToTestDisplayString()}' or its associated symbol to have the attribute.");
 
            Assert.True(seenSymbols.Add(symbol), $"Symbol '{symbol.ToTestDisplayString()}' specified multiple times.");
 
            Assert.True(shouldBeUnsafe || !expectedNoAttributeInSourceSymbols.Contains(symbol),
                $"Unexpected safe '{symbol.ToTestDisplayString()}' in {nameof(expectedNoAttributeInSource)}.");
        }
 
        Symbol getSymbol(object symbolGetter)
        {
            var symbol = symbolGetter switch
            {
                string symbolName => module.GlobalNamespace.GetMember(symbolName),
                Func<ModuleSymbol, Symbol> func => func(module),
                _ => throw ExceptionUtilities.UnexpectedValue(symbolGetter),
            };
            Assert.False(symbol is null, $"Cannot find symbol '{symbolGetter}' in {module.GetType().Name}.");
            return symbol;
        }
    }
 
    [Fact]
    public void RulesAttribute_Synthesized()
    {
        var source = """
            class C;
            """;
 
        CompileAndVerify(source,
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: false, includesAttributeUse: false))
            .VerifyDiagnostics();
 
        var ref1 = CompileAndVerify(source,
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: true, includesAttributeUse: true, isSynthesized: true))
            .VerifyDiagnostics()
            .GetImageReference();
 
        CompileAndVerify("", [ref1],
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: true, includesAttributeUse: true, isSynthesized: true))
            .VerifyDiagnostics();
 
        var source2 = """
            class B;
            """;
 
        CompileAndVerify(source2, [ref1],
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: true, includesAttributeUse: true, isSynthesized: true))
            .VerifyDiagnostics();
 
        CompileAndVerify(source,
            options: TestOptions.ReleaseModule,
            verify: Verification.Skipped,
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: false, includesAttributeUse: false))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            options: TestOptions.ReleaseModule.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS0518: Predefined type 'System.Runtime.CompilerServices.MemorySafetyRulesAttribute' is not defined or imported
            Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Runtime.CompilerServices.MemorySafetyRulesAttribute").WithLocation(1, 1));
 
        // Script compilation.
        source = "System.Console.WriteLine();";
 
        CompileAndVerify(source,
            parseOptions: TestOptions.Script,
            options: TestOptions.ReleaseModule,
            verify: Verification.Skipped,
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: false, includesAttributeUse: false))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Script,
            options: TestOptions.ReleaseModule.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS0518: Predefined type 'System.Runtime.CompilerServices.MemorySafetyRulesAttribute' is not defined or imported
            Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Runtime.CompilerServices.MemorySafetyRulesAttribute").WithLocation(1, 1));
 
        // No types and members in the compilation, but the attribute is still synthesized if updated rules are enabled.
        source = """
            [assembly: System.Reflection.AssemblyDescriptionAttribute(null)]
            """;
 
        CompileAndVerify(source,
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: false, includesAttributeUse: false))
            .VerifyDiagnostics();
 
        CompileAndVerify(source,
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: true, includesAttributeUse: true, isSynthesized: true))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            options: TestOptions.ReleaseModule.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS0518: Predefined type 'System.Runtime.CompilerServices.MemorySafetyRulesAttribute' is not defined or imported
            Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Runtime.CompilerServices.MemorySafetyRulesAttribute").WithLocation(1, 1));
    }
 
    [Theory, CombinatorialData]
    public void RulesAttribute_TypeForwardedTo(
        bool updatedRulesA,
        bool updatedRulesB,
        bool useCompilationReference)
    {
        var sourceA = """
            public class A { }
            """;
        var comp = CreateCompilation(sourceA,
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(updatedRulesA))
            .VerifyDiagnostics();
        var refA = AsReference(comp, useCompilationReference);
        Assert.Equal(updatedRulesA, comp.SourceModule.UseUpdatedMemorySafetyRules);
        CompileAndVerify(comp,
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: updatedRulesA, includesAttributeUse: updatedRulesA, isSynthesized: updatedRulesA ? true : null))
            .VerifyDiagnostics();
 
        var sourceB = """
            using System.Runtime.CompilerServices;
            [assembly: TypeForwardedTo(typeof(A))]
            """;
        comp = CreateCompilation(sourceB, [refA], options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(updatedRulesB));
        Assert.Equal(updatedRulesB, comp.SourceModule.UseUpdatedMemorySafetyRules);
        CompileAndVerify(comp,
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: updatedRulesB, includesAttributeUse: updatedRulesB, isSynthesized: updatedRulesB ? true : null))
            .VerifyDiagnostics();
    }
 
    [Fact]
    public void RulesAttribute_Reflection()
    {
        var sourceA = """
            using System;
            using System.Linq;
            public class A
            {
                public static int GetAttributeValue(Type type)
                {
                    var module = type.Assembly.Modules.Single();
                    var attribute = module.GetCustomAttributes(inherit: false).Single(a => a.GetType().Name == "MemorySafetyRulesAttribute");
                    var prop = attribute.GetType().GetProperty("Version");
                    return (int)prop.GetValue(attribute);
                }
            }
            """;
        var refA = CreateCompilation(sourceA,
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics()
            .EmitToImageReference();
 
        var sourceB = """
            using System;
            class B : A
            {
                static void Main()
                {
                    Console.Write(GetAttributeValue(typeof(A)));
                    Console.Write(" ");
                    Console.Write(GetAttributeValue(typeof(B)));
                }
            }
            """;
        CompileAndVerify(sourceB, [refA],
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules(),
            expectedOutput: "2 2")
            .VerifyDiagnostics();
    }
 
    [Fact]
    public void RulesAttribute_FromSource()
    {
        var source = """
            class C;
            """;
 
        CompileAndVerify([source, MemorySafetyRulesAttributeDefinition],
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: true, includesAttributeUse: false, isSynthesized: false))
            .VerifyDiagnostics();
 
        CompileAndVerify([source, MemorySafetyRulesAttributeDefinition],
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: true, includesAttributeUse: true, isSynthesized: false))
            .VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void RulesAttribute_FromMetadata(bool useCompilationReference)
    {
        var comp = CreateCompilation(MemorySafetyRulesAttributeDefinition);
        CompileAndVerify(comp,
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: true, includesAttributeUse: false, isSynthesized: false))
            .VerifyDiagnostics();
        var ref1 = AsReference(comp, useCompilationReference);
 
        var source = """
            class C;
            """;
 
        CompileAndVerify(source, [ref1],
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: false, includesAttributeUse: true, isSynthesized: false))
            .VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void RulesAttribute_FromMetadata_Multiple(bool useCompilationReference)
    {
        var comp1 = CreateCompilation(MemorySafetyRulesAttributeDefinition).VerifyDiagnostics();
        var ref1 = AsReference(comp1, useCompilationReference);
 
        var comp2 = CreateCompilation(MemorySafetyRulesAttributeDefinition).VerifyDiagnostics();
        var ref2 = AsReference(comp2, useCompilationReference);
 
        var source = """
            class C;
            """;
 
        // Ambiguous attribute definitions from references => synthesize our own.
        CompileAndVerify(source, [ref1, ref2],
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: true, includesAttributeUse: true, isSynthesized: true))
            .VerifyDiagnostics();
 
        // Also defined in source.
        CompileAndVerify([source, MemorySafetyRulesAttributeDefinition], [ref1, ref2],
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: true, includesAttributeUse: true, isSynthesized: false))
            .VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void RulesAttribute_FromMetadata_Multiple_AndCorLib(bool useCompilationReference)
    {
        var corlibSource = """
            namespace System
            {
                public class Object;
                public class ValueType;
                public class Attribute;
                public struct Void;
                public struct Int32;
                public struct Boolean;
                public class AttributeUsageAttribute
                {
                    public AttributeUsageAttribute(AttributeTargets t) { }
                    public bool AllowMultiple { get; set; }
                    public bool Inherited { get; set; }
                }
                public class Enum;
                public enum AttributeTargets;
            }
            """;
 
        var corlib = CreateEmptyCompilation([corlibSource, MemorySafetyRulesAttributeDefinition]).VerifyDiagnostics();
        var corlibRef = AsReference(corlib, useCompilationReference);
 
        var comp1 = CreateEmptyCompilation(MemorySafetyRulesAttributeDefinition, [corlibRef]).VerifyDiagnostics();
        var ref1 = AsReference(comp1, useCompilationReference);
 
        var comp2 = CreateEmptyCompilation(MemorySafetyRulesAttributeDefinition, [corlibRef]).VerifyDiagnostics();
        var ref2 = AsReference(comp2, useCompilationReference);
 
        var source = """
            class C;
            """;
 
        // Using the attribute from corlib even if there are ambiguous definitions in other references.
        var verifier = CompileAndVerify(CreateEmptyCompilation(source, [ref1, ref2, corlibRef],
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules()),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: false, includesAttributeUse: true, isSynthesized: false));
 
        verifier.Diagnostics.WhereAsArray(d => d.Code != (int)ErrorCode.WRN_NoRuntimeMetadataVersion).Verify();
 
        var comp = (CSharpCompilation)verifier.Compilation;
        Assert.Same(comp.Assembly.CorLibrary, comp.GetReferencedAssemblySymbol(corlibRef));
    }
 
    [Theory]
    [InlineData(0)]
    [InlineData(-1)]
    [InlineData(1)]
    [InlineData(2, true)]
    [InlineData(3)]
    [InlineData(int.MinValue)]
    [InlineData(int.MaxValue)]
    public void RulesAttribute_FromMetadata_Version(int version, bool correctVersion = false)
    {
        // [module: MemorySafetyRules({version})]
        // public class A { public static void M() => throw null; }
        var sourceA = $$"""
            .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
            .assembly '<<GeneratedFileName>>' { }
            .module '<<GeneratedFileName>>.dll'
            .custom instance void System.Runtime.CompilerServices.MemorySafetyRulesAttribute::.ctor(int32) = { int32({{version}}) }
            .class private System.Runtime.CompilerServices.MemorySafetyRulesAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
            }
            .class public A
            {
                .method public static void M() { ldnull throw }
            }
            """;
        var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
        var sourceB = """
            class B
            {
                void M() => A.M();
            }
            """;
        var comp = CreateCompilation(sourceB, [refA]);
        if (correctVersion)
        {
            comp.VerifyEmitDiagnostics();
        }
        else
        {
            comp.VerifyDiagnostics(
                // (3,17): error CS9103: 'A.M()' is defined in a module with an unrecognized System.Runtime.CompilerServices.MemorySafetyRulesAttribute version, expecting '2'.
                //     void M() => A.M();
                Diagnostic(ErrorCode.ERR_UnrecognizedAttributeVersion, "A.M").WithArguments("A.M()", "System.Runtime.CompilerServices.MemorySafetyRulesAttribute", "2").WithLocation(3, 17));
        }
 
        var method = comp.GetMember<MethodSymbol>("B.M");
        Assert.False(method.ContainingModule.UseUpdatedMemorySafetyRules);
 
        // 'A.M' not used => no error.
        CreateCompilation("class C;", references: [refA]).VerifyEmitDiagnostics();
    }
 
    [Theory]
    [InlineData(2, 0, true)]
    [InlineData(0, 2, false)]
    public void RulesAttribute_FromMetadata_Version_Multiple(int version1, int version2, bool correctVersion)
    {
        // [module: MemorySafetyRules({version1})]
        // [module: MemorySafetyRules({version2})]
        // public class A { public static void M() => throw null; }
        var sourceA = $$"""
            .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
            .assembly '<<GeneratedFileName>>' { }
            .module '<<GeneratedFileName>>.dll'
            .custom instance void System.Runtime.CompilerServices.MemorySafetyRulesAttribute::.ctor(int32) = { int32({{version1}}) }
            .custom instance void System.Runtime.CompilerServices.MemorySafetyRulesAttribute::.ctor(int32) = { int32({{version2}}) }
            .class private System.Runtime.CompilerServices.MemorySafetyRulesAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
            }
            .class public A
            {
                .method public static void M() { ldnull throw }
            }
            """;
        var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
        var a = CreateCompilation("", [refA]).GetReferencedAssemblySymbol(refA);
        Assert.Equal(correctVersion, a.Modules.Single().UseUpdatedMemorySafetyRules);
 
        var sourceB = """
            class B
            {
                void M() => A.M();
            }
            """;
        var comp = CreateCompilation(sourceB, [refA]);
        if (correctVersion)
        {
            comp.VerifyEmitDiagnostics();
        }
        else
        {
            comp.VerifyDiagnostics(
                // (3,17): error CS9103: 'A.M()' is defined in a module with an unrecognized System.Runtime.CompilerServices.MemorySafetyRulesAttribute version, expecting '2'.
                //     void M() => A.M();
                Diagnostic(ErrorCode.ERR_UnrecognizedAttributeVersion, "A.M").WithArguments("A.M()", "System.Runtime.CompilerServices.MemorySafetyRulesAttribute", "2").WithLocation(3, 17));
        }
 
        var method = comp.GetMember<MethodSymbol>("B.M");
        Assert.False(method.ContainingModule.UseUpdatedMemorySafetyRules);
 
        // 'A.M' not used => no error.
        CreateCompilation("class C;", references: [refA]).VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void RulesAttribute_FromMetadata_UnrecognizedConstructor_NoArguments()
    {
        // [module: MemorySafetyRules()]
        // public class A { public static void M() => throw null; }
        var sourceA = """
            .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
            .assembly '<<GeneratedFileName>>' { }
            .module '<<GeneratedFileName>>.dll'
            .custom instance void System.Runtime.CompilerServices.MemorySafetyRulesAttribute::.ctor() = ( 01 00 00 00 ) 
            .class private System.Runtime.CompilerServices.MemorySafetyRulesAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
            }
            .class public A
            {
                .method public static void M() { ldnull throw }
            }
            """;
        var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
        var sourceB = """
            class B
            {
                void M() => A.M();
            }
            """;
        var comp = CreateCompilation(sourceB, [refA]);
        comp.VerifyDiagnostics(
            // (3,17): error CS9103: 'A.M()' is defined in a module with an unrecognized System.Runtime.CompilerServices.MemorySafetyRulesAttribute version, expecting '2'.
            //     void M() => A.M();
            Diagnostic(ErrorCode.ERR_UnrecognizedAttributeVersion, "A.M").WithArguments("A.M()", "System.Runtime.CompilerServices.MemorySafetyRulesAttribute", "2").WithLocation(3, 17));
 
        var method = comp.GetMember<MethodSymbol>("B.M");
        Assert.False(method.ContainingModule.UseUpdatedMemorySafetyRules);
 
        // 'A.M' not used => no error.
        CreateCompilation("class C;", references: [refA]).VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void RulesAttribute_FromMetadata_UnrecognizedConstructor_StringArgument()
    {
        // [module: MemorySafetyRules("2")]
        // public class A { public static void M() => throw null; }
        var sourceA = """
            .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
            .assembly '<<GeneratedFileName>>' { }
            .module '<<GeneratedFileName>>.dll'
            .custom instance void System.Runtime.CompilerServices.MemorySafetyRulesAttribute::.ctor(string) = {string('2')}
            .class private System.Runtime.CompilerServices.MemorySafetyRulesAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor(string version) cil managed { ret }
            }
            .class public A
            {
                .method public static void M() { ldnull throw }
            }
            """;
        var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
        var sourceB = """
            class B
            {
                void M() => A.M();
            }
            """;
        var comp = CreateCompilation(sourceB, [refA]);
        comp.VerifyDiagnostics(
            // (3,17): error CS9103: 'A.M()' is defined in a module with an unrecognized System.Runtime.CompilerServices.MemorySafetyRulesAttribute version, expecting '2'.
            //     void M() => A.M();
            Diagnostic(ErrorCode.ERR_UnrecognizedAttributeVersion, "A.M").WithArguments("A.M()", "System.Runtime.CompilerServices.MemorySafetyRulesAttribute", "2").WithLocation(3, 17));
 
        var method = comp.GetMember<MethodSymbol>("B.M");
        Assert.False(method.ContainingModule.UseUpdatedMemorySafetyRules);
 
        // 'A.M' not used => no error.
        CreateCompilation("class C;", references: [refA]).VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void RulesAttribute_MissingConstructor()
    {
        var source1 = """
            namespace System.Runtime.CompilerServices
            {
                public sealed class MemorySafetyRulesAttribute : Attribute { }
            }
            """;
        var source2 = """
            class C;
            """;
 
        CreateCompilation([source1, source2]).VerifyEmitDiagnostics();
 
        CreateCompilation([source1, source2],
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics()
            .VerifyEmitDiagnostics(
            // error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.MemorySafetyRulesAttribute..ctor'
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.Runtime.CompilerServices.MemorySafetyRulesAttribute", ".ctor").WithLocation(1, 1));
 
        CreateCompilation([source1, source2],
            options: TestOptions.ReleaseModule.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.MemorySafetyRulesAttribute..ctor'
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember).WithArguments("System.Runtime.CompilerServices.MemorySafetyRulesAttribute", ".ctor").WithLocation(1, 1));
    }
 
    [Theory, CombinatorialData]
    public void RulesAttribute_ReferencedInSource(
        bool updatedRules,
        bool useCompilationReference)
    {
        var comp = CreateCompilation(MemorySafetyRulesAttributeDefinition).VerifyDiagnostics();
        var ref1 = AsReference(comp, useCompilationReference);
 
        var source = """
            using System.Runtime.CompilerServices;
            [assembly: MemorySafetyRules(2)]
            [module: MemorySafetyRules(2)]
            """;
 
        comp = CreateCompilation(source, [ref1], options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(updatedRules));
        comp.VerifyDiagnostics(
            // (3,10): error CS8335: Do not use 'System.Runtime.CompilerServices.MemorySafetyRulesAttribute'. This is reserved for compiler usage.
            // [module: MemorySafetyRules(2)]
            Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "MemorySafetyRules(2)").WithArguments("System.Runtime.CompilerServices.MemorySafetyRulesAttribute").WithLocation(3, 10));
    }
 
    [Theory, CombinatorialData]
    public void Pointer_Variable_SafeContext(bool allowUnsafe)
    {
        var source = """
            int* x = null;
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 1),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithAllowUnsafe(allowUnsafe)).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithAllowUnsafe(allowUnsafe)).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithAllowUnsafe(allowUnsafe).WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithAllowUnsafe(allowUnsafe).WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithAllowUnsafe(allowUnsafe).WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1));
    }
 
    [Fact]
    public void Pointer_Variable_SafeContext_Var()
    {
        var source = """
            var x = GetPointer();
            int* GetPointer() => null;
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,9): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // var x = GetPointer();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "GetPointer()").WithArguments("updated memory safety rules").WithLocation(1, 9),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* GetPointer() => null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(2, 1));
    }
 
    [Fact]
    public void Pointer_Variable_SafeContext_InIterator()
    {
        var source = """
            unsafe
            {
                M();
                System.Collections.Generic.IEnumerable<int> M()
                {
                    int* p = null;
                    yield return 1;
                }
            }
            """;
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(
            // (6,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //         int* p = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(6, 9));
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (6,9): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //         int* p = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(6, 9));
 
        var expectedDiagnostics = new[]
        {
            // (6,9): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
            //         int* p = null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "int*").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(6, 9),
        };
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular12,
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular12,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Pointer_Variable_UnsafeContext()
    {
        var source = """
            unsafe { int* x = null; }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,1): error CS0227: Unsafe code may only appear if compiling with /unsafe
            // unsafe { int* x = null; }
            Diagnostic(ErrorCode.ERR_IllegalUnsafe, "unsafe").WithLocation(1, 1),
        };
 
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe).VerifyEmitDiagnostics();
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Pointer_Variable_UsingAlias_SafeContext()
    {
        var source = """
            using X = int*;
            X x = null;
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,11): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // using X = int*;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 11),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // X x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "X").WithLocation(2, 1),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,11): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // using X = int*;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 11),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // X x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "X").WithArguments("updated memory safety rules").WithLocation(2, 1));
    }
 
    [Fact]
    public void Pointer_Variable_UsingAlias_UnsafeContext()
    {
        var source = """
            using unsafe X = int*;
            unsafe { X x = null; }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,7): error CS0227: Unsafe code may only appear if compiling with /unsafe
            // using unsafe X = int*;
            Diagnostic(ErrorCode.ERR_IllegalUnsafe, "unsafe").WithLocation(1, 7),
            // (2,1): error CS0227: Unsafe code may only appear if compiling with /unsafe
            // unsafe { X x = null; }
            Diagnostic(ErrorCode.ERR_IllegalUnsafe, "unsafe").WithLocation(2, 1),
        };
 
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe).VerifyEmitDiagnostics();
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void Pointer_Dereference_SafeContext(bool allowUnsafe)
    {
        var source = """
            int* x = null;
            int y = *x;
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithAllowUnsafe(allowUnsafe))
            .VerifyDiagnostics(
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 1),
            // (2,10): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int y = *x;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(2, 10));
 
        var expectedDiagnostics = new[]
        {
            // (2,9): error CS9360: This operation may only be used in an unsafe context
            // int y = *x;
            Diagnostic(ErrorCode.ERR_UnsafeOperation, "*").WithLocation(2, 9),
        };
 
        CreateCompilation(source,
            options: TestOptions.ReleaseExe.WithAllowUnsafe(allowUnsafe).WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithAllowUnsafe(allowUnsafe).WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithAllowUnsafe(allowUnsafe).WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1),
            // (2,10): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int y = *x;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(2, 10),
            // (2,9): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int y = *x;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "*").WithArguments("updated memory safety rules").WithLocation(2, 9));
    }
 
    [Fact]
    public void Pointer_Dereference_SafeContext_InIterator()
    {
        var source = """
            unsafe
            {
                M();
                System.Collections.Generic.IEnumerable<int> M()
                {
                    int* p = null;
                    int y = *p;
                    yield return 1;
                }
            }
            """;
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(
            // (6,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //         int* p = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(6, 9),
            // (7,18): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //         int y = *p;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(7, 18));
 
        var expectedDiagnostics = new[]
        {
            // (7,17): error CS9360: This operation may only be used in an unsafe context
            //         int y = *p;
            Diagnostic(ErrorCode.ERR_UnsafeOperation, "*").WithLocation(7, 17),
        };
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (6,9): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //         int* p = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(6, 9),
            // (7,18): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //         int y = *p;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("updated memory safety rules").WithLocation(7, 18),
            // (7,17): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //         int y = *p;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "*").WithArguments("updated memory safety rules").WithLocation(7, 17));
 
        expectedDiagnostics =
        [
            // (6,9): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
            //         int* p = null;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "int*").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(6, 9),
            // (7,18): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
            //         int y = *p;
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "p").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(7, 18),
        ];
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular12,
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular12,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Pointer_Dereference_SafeContext_Null()
    {
        var source = """
            int x = *null;
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,9): error CS0193: The * or -> operator must be applied to a pointer
            // int x = *null;
            Diagnostic(ErrorCode.ERR_PtrExpected, "*null").WithLocation(1, 9),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Pointer_Dereference_UnsafeContext()
    {
        var source = """
            int* x = null;
            unsafe { int y = *x; }
            """;
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1));
    }
 
    [Fact]
    public void Pointer_MemberAccess_SafeContext()
    {
        var source = """
            int* x = null;
            string s = x->ToString();
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 1),
            // (2,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // string s = x->ToString();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(2, 12));
 
        var expectedDiagnostics = new[]
        {
            // (2,13): error CS9360: This operation may only be used in an unsafe context
            // string s = x->ToString();
            Diagnostic(ErrorCode.ERR_UnsafeOperation, "->").WithLocation(2, 13),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1),
            // (2,12): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // string s = x->ToString();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(2, 12),
            // (2,13): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // string s = x->ToString();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "->").WithArguments("updated memory safety rules").WithLocation(2, 13));
    }
 
    [Fact]
    public void Pointer_MemberAccess_SafeContext_Null()
    {
        var source = """
            string s = null->ToString();
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,12): error CS0193: The * or -> operator must be applied to a pointer
            // string s = null->ToString();
            Diagnostic(ErrorCode.ERR_PtrExpected, "null->ToString").WithLocation(1, 12),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Pointer_MemberAccess_UnsafeContext()
    {
        var source = """
            int* x = null;
            unsafe { string s = x->ToString(); }
            """;
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1));
    }
 
    [Fact]
    public void Pointer_MemberAccessViaDereference_SafeContext()
    {
        var source = """
            int* x = null;
            string s = (*x).ToString();
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 1),
            // (2,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // string s = (*x).ToString();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(2, 14));
 
        var expectedDiagnostics = new[]
        {
            // (2,13): error CS9360: This operation may only be used in an unsafe context
            // string s = (*x).ToString();
            Diagnostic(ErrorCode.ERR_UnsafeOperation, "*").WithLocation(2, 13),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1),
            // (2,14): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // string s = (*x).ToString();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(2, 14),
            // (2,13): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // string s = (*x).ToString();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "*").WithArguments("updated memory safety rules").WithLocation(2, 13));
    }
 
    [Fact]
    public void Pointer_MemberAccessViaDereference_UnsafeContext()
    {
        var source = """
            int* x = null;
            unsafe { string s = (*x).ToString(); }
            """;
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1));
    }
 
    [Fact]
    public void Pointer_ElementAccess_SafeContext()
    {
        var source = """
            int* x = null;
            x[0] = 1;
            int y = x[1];
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 1),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // x[0] = 1;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(2, 1),
            // (3,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int y = x[1];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(3, 9));
 
        var expectedDiagnostics = new[]
        {
            // (2,2): error CS9360: This operation may only be used in an unsafe context
            // x[0] = 1;
            Diagnostic(ErrorCode.ERR_UnsafeOperation, "[").WithLocation(2, 2),
            // (3,10): error CS9360: This operation may only be used in an unsafe context
            // int y = x[1];
            Diagnostic(ErrorCode.ERR_UnsafeOperation, "[").WithLocation(3, 10),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // x[0] = 1;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (2,2): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // x[0] = 1;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "[").WithArguments("updated memory safety rules").WithLocation(2, 2),
            // (3,9): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int y = x[1];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(3, 9),
            // (3,10): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int y = x[1];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "[").WithArguments("updated memory safety rules").WithLocation(3, 10));
    }
 
    [Fact]
    public void Pointer_ElementAccess_SafeContext_MultipleIndices()
    {
        var source = """
            int* x = null;
            x[0, 1] = 1;
            int y = x[2, 3];
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 1),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // x[0, 1] = 1;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(2, 1),
            // (2,1): error CS0196: A pointer must be indexed by only one value
            // x[0, 1] = 1;
            Diagnostic(ErrorCode.ERR_PtrIndexSingle, "x[0, 1]").WithLocation(2, 1),
            // (3,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int y = x[2, 3];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(3, 9),
            // (3,9): error CS0196: A pointer must be indexed by only one value
            // int y = x[2, 3];
            Diagnostic(ErrorCode.ERR_PtrIndexSingle, "x[2, 3]").WithLocation(3, 9));
 
        var expectedDiagnostics = new[]
        {
            // (2,1): error CS0196: A pointer must be indexed by only one value
            // x[0, 1] = 1;
            Diagnostic(ErrorCode.ERR_PtrIndexSingle, "x[0, 1]").WithLocation(2, 1),
            // (3,9): error CS0196: A pointer must be indexed by only one value
            // int y = x[2, 3];
            Diagnostic(ErrorCode.ERR_PtrIndexSingle, "x[2, 3]").WithLocation(3, 9),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // x[0, 1] = 1;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (2,1): error CS0196: A pointer must be indexed by only one value
            // x[0, 1] = 1;
            Diagnostic(ErrorCode.ERR_PtrIndexSingle, "x[0, 1]").WithLocation(2, 1),
            // (3,9): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int y = x[2, 3];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(3, 9),
            // (3,9): error CS0196: A pointer must be indexed by only one value
            // int y = x[2, 3];
            Diagnostic(ErrorCode.ERR_PtrIndexSingle, "x[2, 3]").WithLocation(3, 9));
    }
 
    [Fact]
    public void Pointer_ElementAccess_SafeContext_ArrayOfPointers()
    {
        var source = """
            int*[] x = [];
            x[0] = null;
            _ = x[1];
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int*[] x = [];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 1),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(2, 1),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[0]").WithLocation(2, 1),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[0] = null").WithLocation(2, 1),
            // (3,5): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(3, 5),
            // (3,5): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[1]").WithLocation(3, 5),
            // (3,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "_ = x[1]").WithLocation(3, 1));
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int*[] x = [];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x[0]").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x[0] = null").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (3,5): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(3, 5),
            // (3,5): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x[1]").WithArguments("updated memory safety rules").WithLocation(3, 5),
            // (3,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "_ = x[1]").WithArguments("updated memory safety rules").WithLocation(3, 1));
    }
 
    [Fact]
    public void Pointer_ElementAccess_SafeContext_FunctionPointer()
    {
        var source = """
            delegate*<void> x = null;
            x[0] = null;
            _ = x[1];
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // delegate*<void> x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "delegate*").WithLocation(1, 1),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(2, 1),
            // (2,1): error CS0021: Cannot apply indexing with [] to an expression of type 'delegate*<void>'
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_BadIndexLHS, "x[0]").WithArguments("delegate*<void>").WithLocation(2, 1),
            // (3,5): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(3, 5),
            // (3,5): error CS0021: Cannot apply indexing with [] to an expression of type 'delegate*<void>'
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_BadIndexLHS, "x[1]").WithArguments("delegate*<void>").WithLocation(3, 5));
 
        var expectedDiagnostics = new[]
        {
            // (2,1): error CS0021: Cannot apply indexing with [] to an expression of type 'delegate*<void>'
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_BadIndexLHS, "x[0]").WithArguments("delegate*<void>").WithLocation(2, 1),
            // (3,5): error CS0021: Cannot apply indexing with [] to an expression of type 'delegate*<void>'
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_BadIndexLHS, "x[1]").WithArguments("delegate*<void>").WithLocation(3, 5),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // delegate*<void> x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "delegate*").WithArguments("updated memory safety rules").WithLocation(1, 1),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (2,1): error CS0021: Cannot apply indexing with [] to an expression of type 'delegate*<void>'
            // x[0] = null;
            Diagnostic(ErrorCode.ERR_BadIndexLHS, "x[0]").WithArguments("delegate*<void>").WithLocation(2, 1),
            // (3,5): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("updated memory safety rules").WithLocation(3, 5),
            // (3,5): error CS0021: Cannot apply indexing with [] to an expression of type 'delegate*<void>'
            // _ = x[1];
            Diagnostic(ErrorCode.ERR_BadIndexLHS, "x[1]").WithArguments("delegate*<void>").WithLocation(3, 5));
    }
 
    [Fact]
    public void Pointer_ElementAccess_UnsafeContext()
    {
        var source = """
            int* x = null;
            unsafe
            {
                x[0] = 1;
                int y = x[1];
            }
            """;
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1));
    }
 
    [Fact]
    public void Pointer_Function_Variable_SafeContext()
    {
        var source = """
            delegate*<void> f = null;
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // delegate*<void> f = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "delegate*").WithLocation(1, 1),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // delegate*<void> f = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "delegate*").WithArguments("updated memory safety rules").WithLocation(1, 1));
    }
 
    [Fact]
    public void Pointer_Function_Variable_UnsafeContext()
    {
        var source = """
            unsafe { delegate*<void> f = null; }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,1): error CS0227: Unsafe code may only appear if compiling with /unsafe
            // unsafe { delegate*<void> f = null; }
            Diagnostic(ErrorCode.ERR_IllegalUnsafe, "unsafe").WithLocation(1, 1),
        };
 
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe).VerifyEmitDiagnostics();
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Pointer_Function_Variable_UsingAlias_SafeContext()
    {
        var source = """
            using X = delegate*<void>;
            X x = null;
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,11): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // using X = delegate*<void>;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "delegate*").WithLocation(1, 11),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // X x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "X").WithLocation(2, 1),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        // https://github.com/dotnet/roslyn/issues/77389
        expectedDiagnostics = PlatformInformation.IsWindows
            ? [
                // error CS8911: Using a function pointer type in this context is not supported.
                Diagnostic(ErrorCode.ERR_FunctionPointerTypesInAttributeNotSupported).WithLocation(1, 1),
            ]
            : [];
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics()
            .VerifyEmitDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics()
            .VerifyEmitDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,11): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // using X = delegate*<void>;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "delegate*").WithArguments("updated memory safety rules").WithLocation(1, 11),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // X x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "X").WithArguments("updated memory safety rules").WithLocation(2, 1));
    }
 
    [Fact]
    public void Pointer_Function_Variable_UsingAlias_UnsafeContext()
    {
        var source = """
            using unsafe X = delegate*<void>;
            unsafe { X x = null; }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,7): error CS0227: Unsafe code may only appear if compiling with /unsafe
            // using unsafe X = delegate*<void>;
            Diagnostic(ErrorCode.ERR_IllegalUnsafe, "unsafe").WithLocation(1, 7),
            // (2,1): error CS0227: Unsafe code may only appear if compiling with /unsafe
            // unsafe { X x = null; }
            Diagnostic(ErrorCode.ERR_IllegalUnsafe, "unsafe").WithLocation(2, 1),
        };
 
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        // https://github.com/dotnet/roslyn/issues/77389
        expectedDiagnostics = PlatformInformation.IsWindows
            ? [
                // error CS8911: Using a function pointer type in this context is not supported.
                Diagnostic(ErrorCode.ERR_FunctionPointerTypesInAttributeNotSupported).WithLocation(1, 1),
            ]
            : [];
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics()
            .VerifyEmitDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics()
            .VerifyEmitDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics()
            .VerifyEmitDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics()
            .VerifyEmitDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Pointer_Function_Call_SafeContext()
    {
        var source = """
            delegate*<string> x = null;
            string s = x();
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // delegate*<string> x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "delegate*").WithLocation(1, 1),
            // (2,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // string s = x();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x()").WithLocation(2, 12));
 
        var expectedDiagnostics = new[]
        {
            // (2,12): error CS9360: This operation may only be used in an unsafe context
            // string s = x();
            Diagnostic(ErrorCode.ERR_UnsafeOperation, "x()").WithLocation(2, 12),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // delegate*<string> x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "delegate*").WithArguments("updated memory safety rules").WithLocation(1, 1),
            // (2,12): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // string s = x();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x()").WithArguments("updated memory safety rules").WithLocation(2, 12));
    }
 
    [Fact]
    public void Pointer_Function_Call_UnsafeContext()
    {
        var source = """
            delegate*<string> x = null;
            unsafe { string s = x(); }
            """;
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // delegate*<string> x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "delegate*").WithArguments("updated memory safety rules").WithLocation(1, 1));
    }
 
    [Fact]
    public void Pointer_Function_Call_UsingAlias()
    {
        var source = """
            using X = delegate*<string>;
            X x = null;
            string s = x();
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (1,11): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // using X = delegate*<string>;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "delegate*").WithLocation(1, 11),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // X x = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "X").WithLocation(2, 1),
            // (3,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // string s = x();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x()").WithLocation(3, 12));
 
        var expectedDiagnostics = new[]
        {
            // (3,12): error CS9360: This operation may only be used in an unsafe context
            // string s = x();
            Diagnostic(ErrorCode.ERR_UnsafeOperation, "x()").WithLocation(3, 12),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,11): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // using X = delegate*<string>;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "delegate*").WithArguments("updated memory safety rules").WithLocation(1, 11),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // X x = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "X").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (3,12): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // string s = x();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x()").WithArguments("updated memory safety rules").WithLocation(3, 12));
    }
 
    [Fact]
    public void Pointer_AddressOf_SafeContext()
    {
        var source = """
            int x;
            int* p = &x;
            """;
 
        var expectedDiagnostics = new[]
        {
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* p = &x;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(2, 1),
            // (2,10): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* p = &x;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "&x").WithLocation(2, 10),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* p = &x;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (2,10): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* p = &x;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "&x").WithArguments("updated memory safety rules").WithLocation(2, 10));
    }
 
    [Fact]
    public void Pointer_AddressOf_SafeContext_Const()
    {
        var source = """
            const int x = 1;
            int* p = &x;
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* p = &x;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(2, 1),
            // (2,11): error CS0211: Cannot take the address of the given expression
            // int* p = &x;
            Diagnostic(ErrorCode.ERR_InvalidAddrOp, "x").WithLocation(2, 11));
 
        var expectedDiagnostics = new[]
        {
            // (2,11): error CS0211: Cannot take the address of the given expression
            // int* p = &x;
            Diagnostic(ErrorCode.ERR_InvalidAddrOp, "x").WithLocation(2, 11),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* p = &x;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (2,11): error CS0211: Cannot take the address of the given expression
            // int* p = &x;
            Diagnostic(ErrorCode.ERR_InvalidAddrOp, "x").WithLocation(2, 11));
    }
 
    [Fact]
    public void Pointer_AddressOf_UnsafeContext()
    {
        var source = """
            int x;
            unsafe { int* p = &x; }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (2,1): error CS0227: Unsafe code may only appear if compiling with /unsafe
            // unsafe { int* p = &x; }
            Diagnostic(ErrorCode.ERR_IllegalUnsafe, "unsafe").WithLocation(2, 1),
        };
 
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe).VerifyEmitDiagnostics();
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Pointer_Fixed_SafeContext()
    {
        var source = """
            class C
            {
                static int x;
                static void Main()
                {
                    fixed (int* p = &x) { }
                }
            }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (6,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //         fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "fixed (int* p = &x) { }").WithLocation(6, 9),
            // (6,16): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //         fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(6, 16),
            // (6,25): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //         fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "&x").WithLocation(6, 25),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (6,9): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //         fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "fixed (int* p = &x) { }").WithArguments("updated memory safety rules").WithLocation(6, 9),
            // (6,16): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //         fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(6, 16),
            // (6,25): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //         fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "&x").WithArguments("updated memory safety rules").WithLocation(6, 25));
    }
 
    [Fact]
    public void Pointer_Fixed_PatternBased()
    {
        var source = """
            class C
            {
                static void Main()
                {
                    fixed (int* p = new S()) { }
                }
            }
 
            struct S
            {
                public ref readonly int GetPinnableReference() => throw null;
            }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (5,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //         fixed (int* p = new S()) { }
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "fixed (int* p = new S()) { }").WithLocation(5, 9),
            // (5,16): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //         fixed (int* p = new S()) { }
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(5, 16),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (5,9): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //         fixed (int* p = new S()) { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "fixed (int* p = new S()) { }").WithArguments("updated memory safety rules").WithLocation(5, 9),
            // (5,16): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //         fixed (int* p = new S()) { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(5, 16));
    }
 
    [Fact]
    public void Pointer_Fixed_SafeContext_AlreadyFixed()
    {
        var source = """
            int x;
            fixed (int* p = &x) { }
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "fixed (int* p = &x) { }").WithLocation(2, 1),
            // (2,8): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(2, 8),
            // (2,17): error CS0213: You cannot use the fixed statement to take the address of an already fixed expression
            // fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_FixedNotNeeded, "&x").WithLocation(2, 17));
 
        var expectedDiagnostics = new[]
        {
            // (2,17): error CS0213: You cannot use the fixed statement to take the address of an already fixed expression
            // fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_FixedNotNeeded, "&x").WithLocation(2, 17),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "fixed (int* p = &x) { }").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (2,8): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(2, 8),
            // (2,17): error CS0213: You cannot use the fixed statement to take the address of an already fixed expression
            // fixed (int* p = &x) { }
            Diagnostic(ErrorCode.ERR_FixedNotNeeded, "&x").WithLocation(2, 17));
    }
 
    [Fact]
    public void Pointer_Fixed_UnsafeContext()
    {
        var source = """
            class C
            {
                static int x;
                static void Main()
                {
                    unsafe { fixed (int* p = &x) { } }
                }
            }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (6,9): error CS0227: Unsafe code may only appear if compiling with /unsafe
            //         unsafe { fixed (int* p = &x) { } }
            Diagnostic(ErrorCode.ERR_IllegalUnsafe, "unsafe").WithLocation(6, 9),
        };
 
        CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe).VerifyEmitDiagnostics();
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Pointer_Arithmetic_SafeContext()
    {
        var source = """
            int* p = null;
            p++;
            int* p2 = p + 2;
            long x = p - p;
            bool b = p > p2;
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* p = null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 1),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // p++;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(2, 1),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // p++;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p++").WithLocation(2, 1),
            // (3,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* p2 = p + 2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 1),
            // (3,11): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* p2 = p + 2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(3, 11),
            // (3,11): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* p2 = p + 2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p + 2").WithLocation(3, 11),
            // (4,10): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // long x = p - p;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(4, 10),
            // (4,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // long x = p - p;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(4, 14),
            // (5,10): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // bool b = p > p2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(5, 10),
            // (5,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // bool b = p > p2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p2").WithLocation(5, 14),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe).VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* p = null;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // p++;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // p++;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "p++").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (3,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* p2 = p + 2;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(3, 1),
            // (3,11): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* p2 = p + 2;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("updated memory safety rules").WithLocation(3, 11),
            // (3,11): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* p2 = p + 2;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "p + 2").WithArguments("updated memory safety rules").WithLocation(3, 11),
            // (4,10): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // long x = p - p;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("updated memory safety rules").WithLocation(4, 10),
            // (4,14): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // long x = p - p;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("updated memory safety rules").WithLocation(4, 14),
            // (5,10): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // bool b = p > p2;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("updated memory safety rules").WithLocation(5, 10),
            // (5,14): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // bool b = p > p2;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "p2").WithArguments("updated memory safety rules").WithLocation(5, 14));
    }
 
    [Fact]
    public void SizeOf_SafeContext()
    {
        var source = """
            _ = sizeof(int);
            _ = sizeof(nint);
            _ = sizeof(S);
            struct S;
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (2,5): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context
            // _ = sizeof(nint);
            Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(2, 5),
            // (3,5): error CS0233: 'S' does not have a predefined size, therefore sizeof can only be used in an unsafe context
            // _ = sizeof(S);
            Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(S)").WithArguments("S").WithLocation(3, 5));
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules()).VerifyEmitDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,5): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // _ = sizeof(nint);
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "sizeof(nint)").WithArguments("updated memory safety rules").WithLocation(2, 5),
            // (3,5): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // _ = sizeof(S);
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "sizeof(S)").WithArguments("updated memory safety rules").WithLocation(3, 5));
    }
 
    [Fact]
    public void FixedSizeBuffer_SafeContext()
    {
        var source = """
            var s = new S();
            int* p = s.y;
            int z = s.x[100];
 
            struct S
            {
                public fixed int x[5], y[10];
            }
            """;
 
        CreateCompilation(source, options: TestOptions.ReleaseExe).VerifyDiagnostics(
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* p = s.y;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(2, 1),
            // (2,10): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* p = s.y;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "s.y").WithLocation(2, 10),
            // (3,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int z = s.x[100];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "s.x").WithLocation(3, 9),
            // (7,22): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     public fixed int x[5], y[10];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[5]").WithLocation(7, 22));
 
        var expectedDiagnostics = new[]
        {
            // (3,12): error CS9360: This operation may only be used in an unsafe context
            // int z = s.x[100];
            Diagnostic(ErrorCode.ERR_UnsafeOperation, "[").WithLocation(3, 12),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* p = s.y;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(2, 1),
            // (2,10): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* p = s.y;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "s.y").WithArguments("updated memory safety rules").WithLocation(2, 10),
            // (3,9): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int z = s.x[100];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "s.x").WithArguments("updated memory safety rules").WithLocation(3, 9),
            // (3,12): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int z = s.x[100];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "[").WithArguments("updated memory safety rules").WithLocation(3, 12),
            // (7,22): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public fixed int x[5], y[10];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "x[5]").WithArguments("updated memory safety rules").WithLocation(7, 22));
    }
 
    [Fact]
    public void SkipLocalsInit_NeedsUnsafe()
    {
        var source = """
            class C { [System.Runtime.CompilerServices.SkipLocalsInit] void M() { } }
 
            namespace System.Runtime.CompilerServices
            {
                public class SkipLocalsInitAttribute : Attribute;
            }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,12): error CS0227: Unsafe code may only appear if compiling with /unsafe
            // class C { [System.Runtime.CompilerServices.SkipLocalsInit] void M() { } }
            Diagnostic(ErrorCode.ERR_IllegalUnsafe, "System.Runtime.CompilerServices.SkipLocalsInit").WithLocation(1, 12),
        };
 
        CreateCompilation(source, options: TestOptions.ReleaseDll)
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseDll)
            .VerifyEmitDiagnostics();
 
        CreateCompilation(source, options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void StackAlloc_SafeContext()
    {
        var source = """
            int* x = stackalloc int[3];
            System.Span<int> y = stackalloc int[5];
            M();
 
            [System.Runtime.CompilerServices.SkipLocalsInit]
            void M()
            {
                System.Span<int> a = stackalloc int[5];
                System.Span<int> b = stackalloc int[] { 1 };
                System.Span<int> d = stackalloc int[2] { 1, 2 };
                System.Span<int> e = stackalloc int[3] { 1, 2 };
            }
 
            namespace System.Runtime.CompilerServices
            {
                public class SkipLocalsInitAttribute : Attribute;
            }
            """;
 
        CreateCompilationWithSpan(source, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(
            // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* x = stackalloc int[3];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 1),
            // (1,10): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // int* x = stackalloc int[3];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "stackalloc int[3]").WithLocation(1, 10),
            // (11,26): error CS0847: An array initializer of length '3' is expected
            //     System.Span<int> e = stackalloc int[3] { 1, 2 };
            Diagnostic(ErrorCode.ERR_ArrayInitializerIncorrectLength, "stackalloc int[3] { 1, 2 }").WithArguments("3").WithLocation(11, 26));
 
        var expectedDiagnostics = new[]
        {
            // (8,26): error CS9361: stackalloc expression without an initializer inside SkipLocalsInit may only be used in an unsafe context
            //     System.Span<int> a = stackalloc int[5];
            Diagnostic(ErrorCode.ERR_UnsafeUninitializedStackAlloc, "stackalloc int[5]").WithLocation(8, 26),
            // (11,26): error CS0847: An array initializer of length '3' is expected
            //     System.Span<int> e = stackalloc int[3] { 1, 2 };
            Diagnostic(ErrorCode.ERR_ArrayInitializerIncorrectLength, "stackalloc int[3] { 1, 2 }").WithArguments("3").WithLocation(11, 26),
        };
 
        CreateCompilationWithSpan(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilationWithSpan(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilationWithSpan(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = stackalloc int[3];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("updated memory safety rules").WithLocation(1, 1),
            // (1,10): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // int* x = stackalloc int[3];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "stackalloc int[3]").WithArguments("updated memory safety rules").WithLocation(1, 10),
            // (8,26): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     System.Span<int> a = stackalloc int[5];
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "stackalloc int[5]").WithArguments("updated memory safety rules").WithLocation(8, 26),
            // (11,26): error CS0847: An array initializer of length '3' is expected
            //     System.Span<int> e = stackalloc int[3] { 1, 2 };
            Diagnostic(ErrorCode.ERR_ArrayInitializerIncorrectLength, "stackalloc int[3] { 1, 2 }").WithArguments("3").WithLocation(11, 26));
    }
 
    [Fact]
    public void StackAlloc_UnsafeContext()
    {
        var source = """
            unsafe { System.Span<int> y = stackalloc int[5]; }
            M();
 
            [System.Runtime.CompilerServices.SkipLocalsInit]
            void M()
            {
                unsafe { System.Span<int> a = stackalloc int[5]; }
                unsafe { System.Span<int> e = stackalloc int[3] { 1, 2 }; }
            }
 
            namespace System.Runtime.CompilerServices
            {
                public class SkipLocalsInitAttribute : Attribute;
            }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (8,35): error CS0847: An array initializer of length '3' is expected
            //     unsafe { System.Span<int> e = stackalloc int[3] { 1, 2 }; }
            Diagnostic(ErrorCode.ERR_ArrayInitializerIncorrectLength, "stackalloc int[3] { 1, 2 }").WithArguments("3").WithLocation(8, 35),
        };
 
        CreateCompilationWithSpan(source, options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilationWithSpan(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilationWithSpan(source,
            parseOptions: TestOptions.RegularNext,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilationWithSpan(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void StackAlloc_Lambda()
    {
        var source = """
            var lam = [System.Runtime.CompilerServices.SkipLocalsInit] () =>
            {
                System.Span<int> a = stackalloc int[5];
                int* b = stackalloc int[3];
                unsafe { System.Span<int> c = stackalloc int[1]; }
            };
 
            namespace System.Runtime.CompilerServices
            {
                public class SkipLocalsInitAttribute : Attribute;
            }
            """;
 
        CreateCompilationWithSpan(source, options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,26): error CS9361: stackalloc expression without an initializer inside SkipLocalsInit may only be used in an unsafe context
            //     System.Span<int> a = stackalloc int[5];
            Diagnostic(ErrorCode.ERR_UnsafeUninitializedStackAlloc, "stackalloc int[5]").WithLocation(3, 26));
    }
 
    [Fact]
    public void Member_LangVersion()
    {
        CSharpTestSource source =
        [
            """
            #pragma warning disable CS8321 // unused local function
            [System.Runtime.CompilerServices.RequiresUnsafe] void F() { }
            class C
            {
                [System.Runtime.CompilerServices.RequiresUnsafe] void M() { }
                [System.Runtime.CompilerServices.RequiresUnsafe] int P { get; set; }
 
                [System.Runtime.CompilerServices.RequiresUnsafe] event System.Action E { add { } remove { } }
                [System.Runtime.CompilerServices.RequiresUnsafe] int this[int i] { get => i; set { } }
                [System.Runtime.CompilerServices.RequiresUnsafe] C() { }
                [System.Runtime.CompilerServices.RequiresUnsafe] public static C operator +(C c1, C c2) => c1;
                [System.Runtime.CompilerServices.RequiresUnsafe] public void operator +=(C c) { }
            #pragma warning disable CS0169 // unused field
                [System.Runtime.CompilerServices.RequiresUnsafe] int F;
            }
            [System.Runtime.CompilerServices.RequiresUnsafe] class U;
            [System.Runtime.CompilerServices.RequiresUnsafe] delegate void D();
            """,
            CompilerFeatureRequiredAttribute,
            """
            namespace System.Runtime.CompilerServices
            {
                public sealed class RequiresUnsafeAttribute : Attribute;
            }
            """,
        ];
 
        string[] safeSymbols = ["C", "C.F", "U", "D"];
        string[] unsafeSymbols =
        [
            "Program.<<Main>$>g__F|0_0",
            "C.M",
            "C.P", "C.get_P", "C.set_P",
            "C.E", "C.add_E", "C.remove_E",
            "C.this[]", "C.get_Item", "C.set_Item",
            "C..ctor",
            "C.op_Addition",
            "C.op_AdditionAssignment",
        ];
        string[] symbolsWithAttribute = safeSymbols.Except(["C"]).Concat(unsafeSymbols).ToArray();
 
        CompileAndVerify(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithMetadataImportOptions(MetadataImportOptions.All)
                .WithSpecificDiagnosticOptions(GetIdForErrorCode(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules), ReportDiagnostic.Suppress),
            symbolValidator: m =>
            {
                VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: false, includesAttributeUse: false);
                VerifyRequiresUnsafeAttribute(
                    m,
                    expectedUnsafeSymbols: [],
                    expectedSafeSymbols: [.. safeSymbols, .. unsafeSymbols],
                    expectedAttribute: symbolsWithAttribute);
            })
            .VerifyDiagnostics();
 
        CompileAndVerify(source,
            parseOptions: TestOptions.RegularPreview,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules().WithMetadataImportOptions(MetadataImportOptions.All),
            symbolValidator: m =>
            {
                VerifyMemorySafetyRulesAttribute(m, includesAttributeDefinition: true, includesAttributeUse: true, isSynthesized: true);
                VerifyRequiresUnsafeAttribute(
                    m,
                    expectedUnsafeSymbols: [.. unsafeSymbols],
                    expectedSafeSymbols: [.. safeSymbols],
                    expectedAttribute: symbolsWithAttribute);
            })
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,2): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // [System.Runtime.CompilerServices.RequiresUnsafe] void F() { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(2, 2),
            // (5,6): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [System.Runtime.CompilerServices.RequiresUnsafe] void M() { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(5, 6),
            // (6,6): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [System.Runtime.CompilerServices.RequiresUnsafe] int P { get; set; }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(6, 6),
            // (8,6): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [System.Runtime.CompilerServices.RequiresUnsafe] event System.Action E { add { } remove { } }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(8, 6),
            // (9,6): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [System.Runtime.CompilerServices.RequiresUnsafe] int this[int i] { get => i; set { } }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(9, 6),
            // (10,6): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [System.Runtime.CompilerServices.RequiresUnsafe] C() { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(10, 6),
            // (11,6): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [System.Runtime.CompilerServices.RequiresUnsafe] public static C operator +(C c1, C c2) => c1;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(11, 6),
            // (12,6): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [System.Runtime.CompilerServices.RequiresUnsafe] public void operator +=(C c) { }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(12, 6));
    }
 
    [Theory, CombinatorialData]
    public void Member_Method_Invocation(
        bool apiUpdatedRules,
        bool apiUnsafe,
        [CombinatorialValues(LanguageVersion.CSharp14, LanguageVersionFacts.CSharpNext, LanguageVersion.Preview)] LanguageVersion callerLangVersion,
        bool callerAllowUnsafe,
        bool callerUpdatedRules,
        bool callerUnsafeBlock,
        bool? compilationReference)
    {
        var requiresUnsafeAttribute = apiUnsafe && apiUpdatedRules
            ? "[System.Runtime.CompilerServices.RequiresUnsafe]"
            : "";
 
        var api = $$"""
            public class C
            {
                {{requiresUnsafeAttribute}}
                public void M() => System.Console.Write(111);
            }
            """;
 
        var caller = $"""
            var c = new C();
            {(callerUnsafeBlock ? "unsafe { c.M(); }" : "c.M();")}
            """;
 
        var expectedOutput = "111";
 
        CSharpCompilation comp;
        List<DiagnosticDescription> expectedDiagnostics = [];
 
        if (compilationReference is { } useCompilationReference)
        {
            var apiCompilation = CreateCompilation(
                [api, .. (apiUnsafe && apiUpdatedRules ? new[] { RequiresUnsafeAttributeDefinition } : [])],
                options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules(apiUpdatedRules))
                .VerifyDiagnostics();
            var apiReference = AsReference(apiCompilation, useCompilationReference);
            comp = CreateCompilation(caller, [apiReference],
                parseOptions: TestOptions.Regular.WithLanguageVersion(callerLangVersion),
                options: TestOptions.ReleaseExe.WithAllowUnsafe(callerAllowUnsafe).WithUpdatedMemorySafetyRules(callerUpdatedRules));
        }
        else
        {
            if (apiUpdatedRules != callerUpdatedRules)
            {
                return;
            }
 
            comp = CreateCompilation(
                [api, caller, .. (apiUnsafe && apiUpdatedRules ? new[] { RequiresUnsafeAttributeDefinition } : [])],
                parseOptions: TestOptions.Regular.WithLanguageVersion(callerLangVersion),
                options: TestOptions.ReleaseExe.WithAllowUnsafe(callerAllowUnsafe).WithUpdatedMemorySafetyRules(callerUpdatedRules));
        }
 
        if (!callerAllowUnsafe && callerUnsafeBlock)
        {
            expectedDiagnostics.Add(
                // (2,1): error CS0227: Unsafe code may only appear if compiling with /unsafe
                // unsafe { c.M(); }
                Diagnostic(ErrorCode.ERR_IllegalUnsafe, "unsafe").WithLocation(2, 1));
        }
 
        if (apiUnsafe && apiUpdatedRules && callerUpdatedRules && !callerUnsafeBlock)
        {
            if (callerLangVersion >= LanguageVersionFacts.CSharpNext)
            {
                expectedDiagnostics.Add(
                    // (2,1): error CS9362: 'C.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                    // c.M();
                    Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M()").WithArguments("C.M()").WithLocation(2, 1));
            }
            else
            {
                expectedDiagnostics.Add(
                    // (2,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
                    // c.M();
                    Diagnostic(ErrorCode.ERR_FeatureInPreview, "c.M()").WithArguments("updated memory safety rules").WithLocation(2, 1));
            }
        }
 
        // When compiling API and caller together (no compilationReference), the [RequiresUnsafe] attribute
        // in source also triggers FeatureInPreview if using older language version
        if (compilationReference is null && apiUnsafe && apiUpdatedRules && callerLangVersion < LanguageVersionFacts.CSharpNext)
        {
            expectedDiagnostics.Add(
                // (3,6): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
                //     [System.Runtime.CompilerServices.RequiresUnsafe]
                Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(3, 6));
        }
 
        comp.VerifyDiagnostics([.. expectedDiagnostics]);
 
        if (!comp.GetDiagnostics().HasAnyErrors())
        {
            CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
        }
    }
 
    [Fact]
    public void Member_Method_OverloadResolution()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public static void M() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public static void M(int x) { }
                }
                """,
            caller: """
                C.M();
                C.M(1);
                _ = nameof(C.M);
                unsafe { C.M(1); }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: [Overload("C.M", 1)],
            expectedSafeSymbols: ["C", Overload("C.M", 0)],
            expectedDiagnostics:
            [
                // (2,1): error CS9362: 'C.M(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C.M(1);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "C.M(1)").WithArguments("C.M(int)").WithLocation(2, 1),
            ]);
    }
 
    [Fact]
    public void Member_Method_SafeBoundary()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public void M1() { unsafe { M2(); } }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M2() { }
                }
                """,
            caller: """
                var c = new C();
                c.M1();
                c.M2();
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.M2"],
            expectedSafeSymbols: ["C.M1"],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'C.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.M2();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M2()").WithArguments("C.M2()").WithLocation(3, 1),
            ]);
    }
 
    [Fact]
    public void Member_Method_NameOf()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public static void M() { }
                }
                """,
            caller: """
                _ = nameof(C.M);
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.M"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics: []);
    }
 
    [Fact]
    public void Member_Method_Extension()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public static class E
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public static void M1(this int x) { }
 
                    extension(int x)
                    {
                        [System.Runtime.CompilerServices.RequiresUnsafe]
                        public void M2() { }
                    }
                }
                """,
            caller: """
                123.M1();
                123.M2();
                E.M1(123);
                E.M2(123);
                unsafe { 123.M1(); }
                unsafe { 123.M2(); }
                unsafe { E.M1(123); }
                unsafe { E.M2(123); }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["E.M1", "E.M2", ExtensionMember("E", "M2")],
            expectedSafeSymbols: [],
            expectedDiagnostics:
            [
                // (1,1): error CS9362: 'E.M1(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // 123.M1();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "123.M1()").WithArguments("E.M1(int)").WithLocation(1, 1),
                // (2,1): error CS9362: 'E.extension(int).M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // 123.M2();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "123.M2()").WithArguments("E.extension(int).M2()").WithLocation(2, 1),
                // (3,1): error CS9362: 'E.M1(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // E.M1(123);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "E.M1(123)").WithArguments("E.M1(int)").WithLocation(3, 1),
                // (4,1): error CS9362: 'E.M2(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // E.M2(123);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "E.M2(123)").WithArguments("E.M2(int)").WithLocation(4, 1),
            ]);
    }
 
    [Fact]
    public void Member_Method_InUnsafeClass()
    {
        CompileAndVerifyUnsafe(
            lib: """
                using System.Collections.Generic;
                public unsafe class C
                {
                    public void M1() { }
                    public IEnumerable<int> M2()
                    {
                        yield return 1;
                    }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M3() { }
                }
                """,
            caller: """
                var c = new C();
                c.M1();
                c.M2();
                c.M3();
                unsafe { c.M3(); }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.M3"],
            expectedSafeSymbols: ["C.M1", "C.M2"],
            expectedDiagnostics:
            [
                // (4,1): error CS9362: 'C.M3()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.M3();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M3()").WithArguments("C.M3()").WithLocation(4, 1),
            ]);
    }
 
    [Fact]
    public void Member_Method_ConvertToFunctionPointer()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public static class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public static void M() { }
                }
                """,
            caller: """
                delegate*<void> p1 = &C.M;
                unsafe { delegate*<void> p2 = &C.M; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.M"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,22): error CS9362: 'C.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // delegate*<void> p1 = &C.M;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "&C.M").WithArguments("C.M()").WithLocation(1, 22),
            ],
            expectedDiagnosticsForLegacyCaller:
            [
                // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                // delegate*<void> p1 = &C.M;
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "delegate*").WithLocation(1, 1),
            ]);
    }
 
    [Fact]
    public void Member_Method_ConvertToDelegate()
    {
        // https://github.com/dotnet/roslyn/issues/82546: confirm with LDM that delegates cannot be marked caller-unsafe;
        //      then unsafe modifier on a delegate should result in a warning
        CompileAndVerifyUnsafe(
            lib: """
                public static class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public static void M() { }
                }
                """,
            caller: """
                D1 a = C.M;
                D2 b = C.M;
                unsafe { D1 c = C.M; }
                unsafe { D1 d = C.M; }
 
                delegate void D1();
                unsafe delegate void D2();
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.M"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,8): error CS9362: 'C.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // D1 a = C.M;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "C.M").WithArguments("C.M()").WithLocation(1, 8),
                // (2,8): error CS9362: 'C.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // D2 b = C.M;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "C.M").WithArguments("C.M()").WithLocation(2, 8),
            ]);
    }
 
    [Fact]
    public void Member_Method_Attribute()
    {
        var commonDiagnostics = new[]
        {
            // (3,4): error CS0617: 'F' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, or const, or read-write properties which are public and not static.
            // [A(F = 0)] void M2() { }
            Diagnostic(ErrorCode.ERR_BadNamedAttributeArgument, "F").WithArguments("F").WithLocation(3, 4),
            // (4,13): error CS0617: 'F' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, or const, or read-write properties which are public and not static.
            // unsafe { [A(F = 0)] void M3() { } }
            Diagnostic(ErrorCode.ERR_BadNamedAttributeArgument, "F").WithArguments("F").WithLocation(4, 13),
            // (5,4): error CS0617: 'F' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, or const, or read-write properties which are public and not static.
            // [A(F = 0)] unsafe void M4() { }
            Diagnostic(ErrorCode.ERR_BadNamedAttributeArgument, "F").WithArguments("F").WithLocation(5, 4),
        };
 
        CompileAndVerifyUnsafe(
            lib: """
                public class A : System.Attribute
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void F(int x) { }
                }
                """,
            caller: """
                #pragma warning disable CS8321 // unused local function
                [A] void M1() { }
                [A(F = 0)] void M2() { }
                unsafe { [A(F = 0)] void M3() { } }
                [A(F = 0)] unsafe void M4() { }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["A.F"],
            expectedSafeSymbols: ["A"],
            expectedDiagnostics:
            [
                // (3,4): error CS9362: 'A.F(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // [A(F = 0)] void M2() { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "F = 0").WithArguments("A.F(int)").WithLocation(3, 4),
                .. commonDiagnostics,
            ],
            expectedDiagnosticsWhenReferencingLegacyLib: commonDiagnostics,
            expectedDiagnosticsForLegacyCaller: commonDiagnostics);
    }
 
    [Fact]
    public void Member_Method_Interface()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public interface I
                {
                    void M1();
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    void M2();
                }
                """,
            caller: """
                I i = null;
                i.M1();
                i.M2();
                unsafe { i.M2(); }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["I.M2"],
            expectedSafeSymbols: ["I", "I.M1"],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'I.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // i.M2();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "i.M2()").WithArguments("I.M2()").WithLocation(3, 1),
            ]);
    }
 
    [Fact]
    public void Member_Method_Override_LangVersion()
    {
        var lib = """
            public class B
            {
                public virtual void M1() { }
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public virtual void M2() { }
            }
            """;
 
        var caller = """
            new C().M1();
 
            class C : B
            {
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public override void M1() { }
                public override void M2() { }
            }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (1,1): error CS9362: 'C.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // new C().M1();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C().M1()").WithArguments("C.M1()").WithLocation(1, 1),
            // (6,26): error CS9364: Unsafe member 'C.M1()' cannot override safe member 'B.M1()'
            //     public override void M1() { }
            Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M1").WithArguments("C.M1()", "B.M1()").WithLocation(6, 26),
        };
 
        CompileAndVerifyUnsafe(
            lib: lib,
            caller: caller,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["B.M2"],
            expectedSafeSymbols: ["B.M1"],
            expectedDiagnostics: expectedDiagnostics,
            expectedDiagnosticsWhenReferencingLegacyLib: expectedDiagnostics);
 
        CreateCompilation([lib, caller, RequiresUnsafeAttributeDefinition],
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (4,6): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(4, 6),
            // (5,6): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.Runtime.CompilerServices.RequiresUnsafe").WithArguments("updated memory safety rules").WithLocation(5, 6),
            // (6,26): error CS9364: Unsafe member 'C.M1()' cannot override safe member 'B.M1()'
            //     public override void M1() { }
            Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M1").WithArguments("C.M1()", "B.M1()").WithLocation(6, 26),
            // (1,1): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            // new C().M1();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "new C().M1()").WithArguments("updated memory safety rules").WithLocation(1, 1));
    }
 
    [Fact]
    public void Member_Method_Override()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class B
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public virtual void M1() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public virtual void M2() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public virtual void M3() { }
                    public virtual void M4() { }
                    public virtual void M5() { }
                    public virtual void M6() { }
                }
 
                public class C : B
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override void M1() { }
                    public new virtual void M2() { }
                    public override void M3() { }
                    public override void M4() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public new virtual void M5() { }
                }
                """,
            caller: """
                var d1 = new D1(); d1.M1(); d1.M2(); d1.M3(); d1.M4(); d1.M5(); d1.M6();
                var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
 
                class D1 : C
                {
                    public override void M1() { }
                    public override void M2() { }
                    public override void M3() { }
                    public override void M4() { }
                    public override void M5() { }
                    public override void M6() { }
                    public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M6(); }
                }
 
                class D2 : C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override void M1() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override void M2() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override void M3() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override void M4() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override void M5() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override void M6() { }
                }
 
                class D3 : C;
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["B.M1", "B.M2", "B.M3", "C.M1", "C.M5"],
            expectedSafeSymbols: ["B.M4", "B.M5", "B.M6", "C.M2", "C.M3", "C.M4"],
            expectedDiagnostics:
            [
                // (2,20): error CS9362: 'D2.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M1()").WithArguments("D2.M1()").WithLocation(2, 20),
                // (2,29): error CS9362: 'D2.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M2()").WithArguments("D2.M2()").WithLocation(2, 29),
                // (2,38): error CS9362: 'D2.M3()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M3()").WithArguments("D2.M3()").WithLocation(2, 38),
                // (2,47): error CS9362: 'D2.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M4()").WithArguments("D2.M4()").WithLocation(2, 47),
                // (2,56): error CS9362: 'D2.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M5()").WithArguments("D2.M5()").WithLocation(2, 56),
                // (2,65): error CS9362: 'D2.M6()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M6()").WithArguments("D2.M6()").WithLocation(2, 65),
                // (3,20): error CS9362: 'C.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M1()").WithArguments("C.M1()").WithLocation(3, 20),
                // (3,56): error CS9362: 'C.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M5()").WithArguments("C.M5()").WithLocation(3, 56),
                // (4,11): error CS9362: 'C.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M1()").WithArguments("C.M1()").WithLocation(4, 11),
                // (4,43): error CS9362: 'C.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M5()").WithArguments("C.M5()").WithLocation(4, 43),
                // (14,31): error CS9362: 'C.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M6(); }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "base.M1()").WithArguments("C.M1()").WithLocation(14, 31),
                // (22,26): error CS9364: Unsafe member 'D2.M2()' cannot override safe member 'C.M2()'
                //     public override void M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M2").WithArguments("D2.M2()", "C.M2()").WithLocation(22, 26),
                // (26,26): error CS9364: Unsafe member 'D2.M4()' cannot override safe member 'B.M4()'
                //     public override void M4() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M4").WithArguments("D2.M4()", "B.M4()").WithLocation(26, 26),
                // (30,26): error CS9364: Unsafe member 'D2.M6()' cannot override safe member 'B.M6()'
                //     public override void M6() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M6").WithArguments("D2.M6()", "B.M6()").WithLocation(30, 26),
            ],
            expectedDiagnosticsWhenReferencingLegacyLib:
            [
                // (2,20): error CS9362: 'D2.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M1()").WithArguments("D2.M1()").WithLocation(2, 20),
                // (2,29): error CS9362: 'D2.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M2()").WithArguments("D2.M2()").WithLocation(2, 29),
                // (2,38): error CS9362: 'D2.M3()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M3()").WithArguments("D2.M3()").WithLocation(2, 38),
                // (2,47): error CS9362: 'D2.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M4()").WithArguments("D2.M4()").WithLocation(2, 47),
                // (2,56): error CS9362: 'D2.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M5()").WithArguments("D2.M5()").WithLocation(2, 56),
                // (2,65): error CS9362: 'D2.M6()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d2.M6()").WithArguments("D2.M6()").WithLocation(2, 65),
                // (20,26): error CS9364: Unsafe member 'D2.M1()' cannot override safe member 'B.M1()'
                //     public override void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M1").WithArguments("D2.M1()", "B.M1()").WithLocation(20, 26),
                // (22,26): error CS9364: Unsafe member 'D2.M2()' cannot override safe member 'C.M2()'
                //     public override void M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M2").WithArguments("D2.M2()", "C.M2()").WithLocation(22, 26),
                // (24,26): error CS9364: Unsafe member 'D2.M3()' cannot override safe member 'B.M3()'
                //     public override void M3() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M3").WithArguments("D2.M3()", "B.M3()").WithLocation(24, 26),
                // (26,26): error CS9364: Unsafe member 'D2.M4()' cannot override safe member 'B.M4()'
                //     public override void M4() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M4").WithArguments("D2.M4()", "B.M4()").WithLocation(26, 26),
                // (28,26): error CS9364: Unsafe member 'D2.M5()' cannot override safe member 'C.M5()'
                //     public override void M5() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M5").WithArguments("D2.M5()", "C.M5()").WithLocation(28, 26),
                // (30,26): error CS9364: Unsafe member 'D2.M6()' cannot override safe member 'B.M6()'
                //     public override void M6() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M6").WithArguments("D2.M6()", "B.M6()").WithLocation(30, 26),
            ]);
    }
 
    [Fact]
    public void Member_Method_Override_Metadata()
    {
        // [module: MemorySafetyRules(updated)]
        // public class A
        // {
        //     public virtual void M() { }
        // }
        // public class B : A
        // {
        //     [RequiresUnsafe]
        //     public override void M() { }
        // }
        var refA = CompileIL($$"""
            .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
            .assembly '<<GeneratedFileName>>' { }
            .module '<<GeneratedFileName>>.dll'
            .custom instance void System.Runtime.CompilerServices.MemorySafetyRulesAttribute::.ctor(int32) = { int32({{CSharpCompilationOptions.UpdatedMemorySafetyRulesVersion}}) }
            .class public System.Runtime.CompilerServices.MemorySafetyRulesAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
            }
            .class public System.Runtime.CompilerServices.RequiresUnsafeAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
            }
            .class public A
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
                .method public hidebysig newslot virtual instance void M() cil managed { ret }
            }
            .class public B extends A
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
                .method public hidebysig virtual instance void M() cil managed
                {
                    .custom instance void System.Runtime.CompilerServices.RequiresUnsafeAttribute::.ctor()
                    ret
                }
            }
            """,
            prependDefaultHeader: false);
 
        var moduleA = CreateCompilation("", [refA]).GetReferencedAssemblySymbol(refA).Modules.Single();
        VerifyMemorySafetyRulesAttribute(
            moduleA,
            includesAttributeDefinition: true,
            isSynthesized: false,
            includesAttributeUse: true);
        VerifyRequiresUnsafeAttribute(
            moduleA,
            expectedUnsafeSymbols: ["B.M"],
            expectedSafeSymbols: ["A", "A.M", "B"]);
 
        CreateCompilation("""
            var c1 = new C1();
            c1.M();
            var c2 = new C2();
            c2.M();
            B b = c2;
            b.M();
            A a = b;
            a.M();
 
            class C1 : B
            {
                public override void M() { }
            }
            class C2 : B
            {
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public override void M() { }
            }
            """,
            [refA],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (4,1): error CS9362: 'C2.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // c2.M();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c2.M()").WithArguments("C2.M()").WithLocation(4, 1),
            // (6,1): error CS9362: 'B.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // b.M();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "b.M()").WithArguments("B.M()").WithLocation(6, 1),
            // (17,26): error CS9364: Unsafe member 'C2.M()' cannot override safe member 'A.M()'
            //     public override void M() { }
            Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M").WithArguments("C2.M()", "A.M()").WithLocation(17, 26));
    }
 
    [Fact]
    public void Member_Method_Implementation()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public interface I1
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    void M1();
                    void M2();
                }
 
                public interface I2
                {
                    void M1();
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    void M2();
                }
 
                public class C1 : I1
                {
                    public void M1() { }
                    public void M2() { }
                }
 
                public class C2 : I1
                {
                    void I1.M1() { }
                    void I1.M2() { }
                }
                """,
            caller: """
                var c5 = new C5();
                I1 i1 = c5;
                i1.M1();
                i1.M2();
                I2 i2 = c5;
                i2.M1();
                i2.M2();
 
                public class C3 : I1
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M1() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M2() { }
                }
 
                public class C4 : I1
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    void I1.M1() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    void I1.M2() { }
                }
 
                public class C5 : I1, I2
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M1() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M2() { }
                }
 
                public class C6 : I2, I1
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M1() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M2() { }
                }
 
                public class C7 : I1, I2
                {
                    public void M1() { }
                    public void M2() { }
                }
 
                public class C8 : I2, I1
                {
                    public void M1() { }
                    public void M2() { }
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["I1.M1", "I2.M2"],
            expectedSafeSymbols: ["I1.M2", "I2.M1", "C1.M1", "C1.M2", "C2.I1.M1", "C2.I1.M2"],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'I1.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // i1.M1();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "i1.M1()").WithArguments("I1.M1()").WithLocation(3, 1),
                // (7,1): error CS9362: 'I2.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // i2.M2();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "i2.M2()").WithArguments("I2.M2()").WithLocation(7, 1),
                // (14,17): error CS9365: Unsafe member 'C3.M2()' cannot implicitly implement safe member 'I1.M2()'
                //     public void M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M2").WithArguments("C3.M2()", "I1.M2()").WithLocation(14, 17),
                // (22,13): error CS9366: Unsafe member 'C4.I1.M2()' cannot implement safe member 'I1.M2()'
                //     void I1.M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeExplicitlyImplementingSafe, "M2").WithArguments("C4.I1.M2()", "I1.M2()").WithLocation(22, 13),
                // (28,17): error CS9365: Unsafe member 'C5.M1()' cannot implicitly implement safe member 'I2.M1()'
                //     public void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("C5.M1()", "I2.M1()").WithLocation(28, 17),
                // (30,17): error CS9365: Unsafe member 'C5.M2()' cannot implicitly implement safe member 'I1.M2()'
                //     public void M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M2").WithArguments("C5.M2()", "I1.M2()").WithLocation(30, 17),
                // (36,17): error CS9365: Unsafe member 'C6.M1()' cannot implicitly implement safe member 'I2.M1()'
                //     public void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("C6.M1()", "I2.M1()").WithLocation(36, 17),
                // (38,17): error CS9365: Unsafe member 'C6.M2()' cannot implicitly implement safe member 'I1.M2()'
                //     public void M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M2").WithArguments("C6.M2()", "I1.M2()").WithLocation(38, 17),
            ],
            expectedDiagnosticsWhenReferencingLegacyLib:
            [
                // (12,17): error CS9365: Unsafe member 'C3.M1()' cannot implicitly implement safe member 'I1.M1()'
                //     public void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("C3.M1()", "I1.M1()").WithLocation(12, 17),
                // (14,17): error CS9365: Unsafe member 'C3.M2()' cannot implicitly implement safe member 'I1.M2()'
                //     public void M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M2").WithArguments("C3.M2()", "I1.M2()").WithLocation(14, 17),
                // (20,13): error CS9366: Unsafe member 'C4.I1.M1()' cannot implement safe member 'I1.M1()'
                //     void I1.M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeExplicitlyImplementingSafe, "M1").WithArguments("C4.I1.M1()", "I1.M1()").WithLocation(20, 13),
                // (22,13): error CS9366: Unsafe member 'C4.I1.M2()' cannot implement safe member 'I1.M2()'
                //     void I1.M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeExplicitlyImplementingSafe, "M2").WithArguments("C4.I1.M2()", "I1.M2()").WithLocation(22, 13),
                // (28,17): error CS9365: Unsafe member 'C5.M1()' cannot implicitly implement safe member 'I1.M1()'
                //     public void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("C5.M1()", "I1.M1()").WithLocation(28, 17),
                // (28,17): error CS9365: Unsafe member 'C5.M1()' cannot implicitly implement safe member 'I2.M1()'
                //     public void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("C5.M1()", "I2.M1()").WithLocation(28, 17),
                // (30,17): error CS9365: Unsafe member 'C5.M2()' cannot implicitly implement safe member 'I1.M2()'
                //     public void M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M2").WithArguments("C5.M2()", "I1.M2()").WithLocation(30, 17),
                // (30,17): error CS9365: Unsafe member 'C5.M2()' cannot implicitly implement safe member 'I2.M2()'
                //     public void M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M2").WithArguments("C5.M2()", "I2.M2()").WithLocation(30, 17),
                // (36,17): error CS9365: Unsafe member 'C6.M1()' cannot implicitly implement safe member 'I2.M1()'
                //     public void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("C6.M1()", "I2.M1()").WithLocation(36, 17),
                // (36,17): error CS9365: Unsafe member 'C6.M1()' cannot implicitly implement safe member 'I1.M1()'
                //     public void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("C6.M1()", "I1.M1()").WithLocation(36, 17),
                // (38,17): error CS9365: Unsafe member 'C6.M2()' cannot implicitly implement safe member 'I2.M2()'
                //     public void M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M2").WithArguments("C6.M2()", "I2.M2()").WithLocation(38, 17),
                // (38,17): error CS9365: Unsafe member 'C6.M2()' cannot implicitly implement safe member 'I1.M2()'
                //     public void M2() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M2").WithArguments("C6.M2()", "I1.M2()").WithLocation(38, 17),
            ]);
    }
 
    [Fact]
    public void Member_Method_Implementation_Synthesized()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class B<T>
                {
                    public void M1(T x) { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M2(T x) { }
                }
                """,
            caller: """
                var c = new C();
                c.M1(null);
                c.M2(null);
 
                class C : B<D>, I;
 
                class D;
 
                interface I
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    void M1(D x);
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["B.M2"],
            expectedSafeSymbols: ["B.M1"],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'B<D>.M2(D)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.M2(null);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M2(null)").WithArguments("B<D>.M2(D)").WithLocation(3, 1),
            ]);
    }
 
    [Fact]
    public void Member_Method_OverrideOfImplementation()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public interface I
                {
                    void M1();
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    void M2();
                }
 
                public class B1 : I
                {
                    public virtual void M1() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public virtual void M2() { }
                }
                """,
            caller: """
                var c1 = new C1();
                c1.M1();
                c1.M2();
                B1 b1 = c1;
                b1.M1();
                b1.M2();
                I i = b1;
                i.M1();
                i.M2();
 
                class B2 : I
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public virtual void M1() { }
                    public virtual void M2() { }
                }
 
                class C1 : B1
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override void M1() { }
                    public override void M2() { }
                }
 
                class C2 : B1, I
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override void M1() { }
                    public override void M2() { }
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["I.M2", "B1.M2"],
            expectedSafeSymbols: ["I.M1", "B1.M1"],
            expectedDiagnostics:
            [
                // (2,1): error CS9362: 'C1.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c1.M1();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c1.M1()").WithArguments("C1.M1()").WithLocation(2, 1),
                // (6,1): error CS9362: 'B1.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // b1.M2();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "b1.M2()").WithArguments("B1.M2()").WithLocation(6, 1),
                // (9,1): error CS9362: 'I.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // i.M2();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "i.M2()").WithArguments("I.M2()").WithLocation(9, 1),
                // (14,25): error CS9365: Unsafe member 'B2.M1()' cannot implicitly implement safe member 'I.M1()'
                //     public virtual void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("B2.M1()", "I.M1()").WithLocation(14, 25),
                // (21,26): error CS9364: Unsafe member 'C1.M1()' cannot override safe member 'B1.M1()'
                //     public override void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M1").WithArguments("C1.M1()", "B1.M1()").WithLocation(21, 26),
                // (28,26): error CS9364: Unsafe member 'C2.M1()' cannot override safe member 'B1.M1()'
                //     public override void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M1").WithArguments("C2.M1()", "B1.M1()").WithLocation(28, 26),
                // (28,26): error CS9365: Unsafe member 'C2.M1()' cannot implicitly implement safe member 'I.M1()'
                //     public override void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("C2.M1()", "I.M1()").WithLocation(28, 26),
            ],
            expectedDiagnosticsWhenReferencingLegacyLib:
            [
                // (2,1): error CS9362: 'C1.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c1.M1();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c1.M1()").WithArguments("C1.M1()").WithLocation(2, 1),
                // (14,25): error CS9365: Unsafe member 'B2.M1()' cannot implicitly implement safe member 'I.M1()'
                //     public virtual void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("B2.M1()", "I.M1()").WithLocation(14, 25),
                // (21,26): error CS9364: Unsafe member 'C1.M1()' cannot override safe member 'B1.M1()'
                //     public override void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M1").WithArguments("C1.M1()", "B1.M1()").WithLocation(21, 26),
                // (28,26): error CS9364: Unsafe member 'C2.M1()' cannot override safe member 'B1.M1()'
                //     public override void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M1").WithArguments("C2.M1()", "B1.M1()").WithLocation(28, 26),
                // (28,26): error CS9365: Unsafe member 'C2.M1()' cannot implicitly implement safe member 'I.M1()'
                //     public override void M1() { }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("C2.M1()", "I.M1()").WithLocation(28, 26),
            ]);
    }
 
    /// <summary>
    /// Caller-unsafety should not count as part of the signature for hiding purposes.
    /// </summary>
    [Fact]
    public void Member_Method_Hiding()
    {
        DiagnosticDescription[] commonDiagnostics =
        [
            // (7,17): warning CS0108: 'C1.M1()' hides inherited member 'B.M1()'. Use the new keyword if hiding was intended.
            //     public void M1() { }
            Diagnostic(ErrorCode.WRN_NewRequired, "M1").WithArguments("C1.M1()", "B.M1()").WithLocation(7, 17),
            // (9,17): warning CS0108: 'C1.M2()' hides inherited member 'B.M2()'. Use the new keyword if hiding was intended.
            //     public void M2() { }
            Diagnostic(ErrorCode.WRN_NewRequired, "M2").WithArguments("C1.M2()", "B.M2()").WithLocation(9, 17),
            // (16,17): error CS0111: Type 'C2' already defines a member called 'M1' with the same parameter types
            //     public void M1() { }
            Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M1").WithArguments("M1", "C2").WithLocation(16, 17),
        ];
 
        DiagnosticDescription[] updatedCallerDiagnostics =
        [
            // (3,1): error CS9362: 'C1.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // c.M2();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M2()").WithArguments("C1.M2()").WithLocation(3, 1),
            .. commonDiagnostics,
        ];
 
        CompileAndVerifyUnsafe(
            lib: """
                public class B
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M1() { }
                    public void M2() { }
                }
                """,
            caller: """
                var c = new C1();
                c.M1();
                c.M2();
 
                class C1 : B
                {
                    public void M1() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M2() { }
                }
 
                class C2
                {
                    public void M1() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void M1() { }
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["B.M1"],
            expectedSafeSymbols: ["B.M2"],
            expectedDiagnostics: updatedCallerDiagnostics,
            expectedDiagnosticsWhenReferencingLegacyLib: updatedCallerDiagnostics,
            expectedDiagnosticsForLegacyCaller: commonDiagnostics);
    }
 
    [Fact]
    public void Member_Await()
    {
        static string getLib(string onCompletedAttribute) => $$"""
            using System;
            using System.Runtime.CompilerServices;
 
            public class C : INotifyCompletion
            {
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public bool IsCompleted => false;
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public C GetAwaiter() => this;
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public void GetResult() { }
                {{onCompletedAttribute}}
                public void OnCompleted(Action continuation) { }
            }
            """;
 
        CreateCompilation(
            [getLib("[System.Runtime.CompilerServices.RequiresUnsafe]"), RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (13,17): error CS9365: Unsafe member 'C.OnCompleted(Action)' cannot implicitly implement safe member 'INotifyCompletion.OnCompleted(Action)'
            //     public void OnCompleted(Action continuation) { }
            Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "OnCompleted").WithArguments("C.OnCompleted(System.Action)", "System.Runtime.CompilerServices.INotifyCompletion.OnCompleted(System.Action)").WithLocation(13, 17));
 
        var lib = getLib("");
 
        CompileAndVerifyUnsafe(
            lib: lib,
            caller: """
                await new C();
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.IsCompleted", "C.GetAwaiter", "C.GetResult"],
            expectedSafeSymbols: ["C", "C.OnCompleted"],
            expectedDiagnostics:
            [
                // (1,1): error CS9362: 'C.GetAwaiter()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // await new C();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "await new C()").WithArguments("C.GetAwaiter()").WithLocation(1, 1),
                // (1,1): error CS9362: 'C.IsCompleted.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // await new C();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "await new C()").WithArguments("C.IsCompleted.get").WithLocation(1, 1),
                // (1,1): error CS9362: 'C.GetResult()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // await new C();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "await new C()").WithArguments("C.GetResult()").WithLocation(1, 1),
            ]);
 
        CreateCompilation(
            [
                lib,
                RequiresUnsafeAttributeDefinition,
                """
                unsafe { await new C(); }
                """,
            ],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,10): error CS4004: Cannot await in an unsafe context
            // unsafe { await new C(); }
            Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await new C()").WithLocation(1, 10));
    }
 
    [Fact]
    public void Member_AsyncHelpers()
    {
        var corlib = CreateEmptyCompilation(
            """
            namespace System
            {
                public class Object;
                public class ValueType;
                public class Attribute;
                public struct Void;
                public struct Int32;
                public struct Boolean;
                public class AttributeUsageAttribute
                {
                    public AttributeUsageAttribute(AttributeTargets t) { }
                    public bool AllowMultiple { get; set; }
                    public bool Inherited { get; set; }
                }
                public class Enum;
                public enum AttributeTargets;
                public class String;
                public class Action;
            }
            namespace System.Runtime.CompilerServices
            {
                public interface INotifyCompletion;
                public static class AsyncHelpers
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public static void AwaitAwaiter<TAwaiter>(TAwaiter awaiter) where TAwaiter : INotifyCompletion { }
                }
                public class RequiresUnsafeAttribute : Attribute { }
            }
            namespace System.Threading.Tasks
            {
                public class Task : System.Runtime.CompilerServices.INotifyCompletion
                {
                    public bool IsCompleted => false;
                    public Task GetAwaiter() => this;
                    public void GetResult() { }
                    public void OnCompleted(Action continuation) { }
                }
            }
            """,
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics()
            .EmitToImageReference();
 
        CreateEmptyCompilation("""
            using System.Threading.Tasks;
 
            class Test
            {
                public static async Task F()
                {
                    await new Task();
                }
            }
            """,
            [corlib],
            parseOptions: WithRuntimeAsync(TestOptions.RegularPreview),
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (7,15): error CS9362: 'AsyncHelpers.AwaitAwaiter<Task>(Task)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            //         await new Task();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new Task()").WithArguments("System.Runtime.CompilerServices.AsyncHelpers.AwaitAwaiter<System.Threading.Tasks.Task>(System.Threading.Tasks.Task)").WithLocation(7, 15));
 
        CreateEmptyCompilation("""
            using System.Threading.Tasks;
 
            class Test
            {
                public static async Task F()
                {
                    unsafe { await new Task(); }
                }
            }
            """,
            [corlib],
            parseOptions: WithRuntimeAsync(TestOptions.RegularPreview),
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (7,18): error CS4004: Cannot await in an unsafe context
            //         unsafe { await new Task(); }
            Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await new Task()").WithLocation(7, 18));
    }
 
    [Fact]
    public void Member_CollectionBuilder_Create()
    {
        CompileAndVerifyUnsafe(
            lib: """
                using System;
                using System.Collections;
                using System.Collections.Generic;
                using System.Runtime.CompilerServices;
 
                [CollectionBuilder(typeof(C), nameof(Create))]
                public class C : IEnumerable<int>
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public static C Create(ReadOnlySpan<int> s) => new C();
                    public IEnumerator<int> GetEnumerator() => throw null;
                    IEnumerator IEnumerable.GetEnumerator() => throw null;
                }
                """,
            caller: """
                C c1 = [1, 2, 3];
                M(1, 2, 3);
                static void M(params C c) { }
 
                unsafe
                {
                    C c2 = [1, 2, 3];
                    M2(1, 2, 3);
                    static void M2(params C c) { }
                }
 
                M3(1, 2, 3);
                static unsafe void M3(params C c) { }
                """,
            additionalSources: [TestSources.Span, CollectionBuilderAttributeDefinition, RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["C.Create"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,8): error CS9362: 'C.Create(ReadOnlySpan<int>)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c1 = [1, 2, 3];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "[1, 2, 3]").WithArguments("C.Create(System.ReadOnlySpan<int>)").WithLocation(1, 8),
                // (2,1): error CS9362: 'C.Create(ReadOnlySpan<int>)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // M(1, 2, 3);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "M(1, 2, 3)").WithArguments("C.Create(System.ReadOnlySpan<int>)").WithLocation(2, 1),
                // (3,15): error CS9362: 'C.Create(ReadOnlySpan<int>)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // static void M(params C c) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "params C c").WithArguments("C.Create(System.ReadOnlySpan<int>)").WithLocation(3, 15),
                // (12,1): error CS9362: 'C.Create(ReadOnlySpan<int>)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // M3(1, 2, 3);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "M3(1, 2, 3)").WithArguments("C.Create(System.ReadOnlySpan<int>)").WithLocation(12, 1),
            ]);
    }
 
    [Fact]
    public void Member_CollectionBuilder_GetEnumerator()
    {
        CompileAndVerifyUnsafe(
            lib: """
                using System;
                using System.Collections;
                using System.Collections.Generic;
                using System.Runtime.CompilerServices;
 
                [CollectionBuilder(typeof(C), nameof(Create))]
                public class C : IEnumerable<int>
                {
                    public static C Create(ReadOnlySpan<int> s) => new C();
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public IEnumerator<int> GetEnumerator() => null;
                    IEnumerator<int> IEnumerable<int>.GetEnumerator() => null;
                    IEnumerator IEnumerable.GetEnumerator() => null;
                }
                """,
            caller: """
                C c1 = [1, 2, 3];
                M(1, 2, 3);
                static void M(params C c) { }
                """,
            additionalSources: [TestSources.Span, CollectionBuilderAttributeDefinition, RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["C.GetEnumerator"],
            expectedSafeSymbols: ["C", "C.Create"],
            expectedDiagnostics: []);
    }
 
    [Fact]
    public void Member_CollectionConstructor()
    {
        CompileAndVerifyUnsafe(
            lib: """
                using System.Collections;
                using System.Collections.Generic;
 
                public class C : IEnumerable<int>
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public C() { }
                    public void Add(int x) { }
                    public IEnumerator<int> GetEnumerator() => throw null;
                    IEnumerator IEnumerable.GetEnumerator() => throw null;
                }
                """,
            caller: """
                C c1 = [1, 2, 3];
                M1(1, 2, 3);
                static void M1(params C c) { }
 
                unsafe
                {
                    C c2 = [1, 2, 3];
                    M2(1, 2, 3);
                    static void M2(params C c) { }
                }
 
                M3(1, 2, 3);
                static unsafe void M3(params C c) { }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C..ctor"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,8): error CS9362: 'C.C()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c1 = [1, 2, 3];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "[1, 2, 3]").WithArguments("C.C()").WithLocation(1, 8),
                // (2,1): error CS9362: 'C.C()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // M1(1, 2, 3);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "M1(1, 2, 3)").WithArguments("C.C()").WithLocation(2, 1),
                // (3,16): error CS9362: 'C.C()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // static void M1(params C c) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "params C c").WithArguments("C.C()").WithLocation(3, 16),
                // (12,1): error CS9362: 'C.C()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // M3(1, 2, 3);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "M3(1, 2, 3)").WithArguments("C.C()").WithLocation(12, 1),
            ]);
    }
 
    [Fact]
    public void Member_CollectionAddMethod()
    {
        CompileAndVerifyUnsafe(
            lib: """
                using System.Collections;
                using System.Collections.Generic;
 
                public class C : IEnumerable<int>
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void Add(int x) { }
                    public IEnumerator<int> GetEnumerator() => throw null;
                    IEnumerator IEnumerable.GetEnumerator() => throw null;
                }
                """,
            caller: """
                C c1 = [1, 2, 3];
                C c2 = new() { 1, 2, 3 };
                C c3 = [.. new C()];
                X x1 = new() { F = { 1, 2, 3 } };
                M1(1, 2, 3);
                static void M1(params C c) { }
 
                unsafe
                {
                    C c4 = [1, 2, 3];
                    C c5 = new() { 1, 2, 3 };
                    C c6 = [.. new C()];
                    X x2 = new() { F = { 1, 2, 3 } };
                    M2(1, 2, 3);
                    static void M2(params C c) { }
                }
 
                M3(1, 2, 3);
                static unsafe void M3(params C c) { }
 
                class X { public C F; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.Add"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,9): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c1 = [1, 2, 3];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "1").WithArguments("C.Add(int)").WithLocation(1, 9),
                // (1,12): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c1 = [1, 2, 3];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "2").WithArguments("C.Add(int)").WithLocation(1, 12),
                // (1,15): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c1 = [1, 2, 3];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "3").WithArguments("C.Add(int)").WithLocation(1, 15),
                // (2,16): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c2 = new() { 1, 2, 3 };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "1").WithArguments("C.Add(int)").WithLocation(2, 16),
                // (2,19): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c2 = new() { 1, 2, 3 };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "2").WithArguments("C.Add(int)").WithLocation(2, 19),
                // (2,22): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c2 = new() { 1, 2, 3 };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "3").WithArguments("C.Add(int)").WithLocation(2, 22),
                // (3,12): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c3 = [.. new C()];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C()").WithArguments("C.Add(int)").WithLocation(3, 12),
                // (4,22): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // X x1 = new() { F = { 1, 2, 3 } };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "1").WithArguments("C.Add(int)").WithLocation(4, 22),
                // (4,25): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // X x1 = new() { F = { 1, 2, 3 } };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "2").WithArguments("C.Add(int)").WithLocation(4, 25),
                // (4,28): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // X x1 = new() { F = { 1, 2, 3 } };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "3").WithArguments("C.Add(int)").WithLocation(4, 28),
                // (5,4): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // M1(1, 2, 3);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "1").WithArguments("C.Add(int)").WithLocation(5, 4),
                // (5,7): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // M1(1, 2, 3);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "2").WithArguments("C.Add(int)").WithLocation(5, 7),
                // (5,10): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // M1(1, 2, 3);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "3").WithArguments("C.Add(int)").WithLocation(5, 10),
                // (6,16): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // static void M1(params C c) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "params C c").WithArguments("C.Add(int)").WithLocation(6, 16),
                // (18,4): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // M3(1, 2, 3);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "1").WithArguments("C.Add(int)").WithLocation(18, 4),
                // (18,7): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // M3(1, 2, 3);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "2").WithArguments("C.Add(int)").WithLocation(18, 7),
                // (18,10): error CS9362: 'C.Add(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // M3(1, 2, 3);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "3").WithArguments("C.Add(int)").WithLocation(18, 10),
            ]);
    }
 
    [Fact]
    public void Member_GetEnumerator()
    {
        CompileAndVerifyUnsafe(
            lib: """
                using System.Collections;
                using System.Collections.Generic;
 
                public class C : IEnumerable<int>
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public IEnumerator<int> GetEnumerator() => null;
                    IEnumerator<int> IEnumerable<int>.GetEnumerator() => null;
                    IEnumerator IEnumerable.GetEnumerator() => null;
                }
                """,
            caller: """
                foreach (var c in new C()) { }
                unsafe { foreach (var c in new C()) { } }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.GetEnumerator"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,1): error CS9362: 'C.GetEnumerator()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // foreach (var c in new C()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "foreach").WithArguments("C.GetEnumerator()").WithLocation(1, 1),
            ]);
    }
 
    [Fact]
    public void Member_GetEnumerator_Spread()
    {
        CompileAndVerifyUnsafe(
            lib: """
                using System.Collections;
                using System.Collections.Generic;
 
                public class C : IEnumerable<int>
                {
                    public void Add(int x) { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public C GetEnumerator() => this;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public bool MoveNext() => false;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int Current => 0;
                    IEnumerator<int> IEnumerable<int>.GetEnumerator() => null;
                    IEnumerator IEnumerable.GetEnumerator() => null;
                }
                """,
            caller: """
                C c1 = [.. new C()];
                unsafe { C c2 = [.. new C()]; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.GetEnumerator", "C.MoveNext", "C.Current", "C.get_Current"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,9): error CS9362: 'C.GetEnumerator()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c1 = [.. new C()];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "..").WithArguments("C.GetEnumerator()").WithLocation(1, 9),
                // (1,9): error CS9362: 'C.MoveNext()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c1 = [.. new C()];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "..").WithArguments("C.MoveNext()").WithLocation(1, 9),
                // (1,9): error CS9362: 'C.Current.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c1 = [.. new C()];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "..").WithArguments("C.Current.get").WithLocation(1, 9),
            ]);
    }
 
    [Fact]
    public void Member_MoveNext()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public C GetEnumerator() => this;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public bool MoveNext() => false;
                    public int Current => 0;
                }
                """,
            caller: """
                foreach (var x in new C()) { }
                unsafe { foreach (var x in new C()) { } }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.MoveNext"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,1): error CS9362: 'C.MoveNext()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // foreach (var x in new C()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "foreach").WithArguments("C.MoveNext()").WithLocation(1, 1),
            ]);
    }
 
    [Theory]
    [InlineData("=> 0;")]
    [InlineData("{ get => 0; }")]
    public void Member_Current_Property(string getter)
    {
        CompileAndVerifyUnsafe(
            lib: $$"""
                public class C
                {
                    public C GetEnumerator() => this;
                    public bool MoveNext() => false;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int Current {{getter}}
                }
                """,
            caller: """
                foreach (var x in new C()) { }
                unsafe { foreach (var x in new C()) { } }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.Current", "C.get_Current"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,1): error CS9362: 'C.Current.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // foreach (var x in new C()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "foreach").WithArguments("C.Current.get").WithLocation(1, 1),
            ]);
    }
 
    [Fact]
    public void Member_Current_Getter()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public C GetEnumerator() => this;
                    public bool MoveNext() => false;
                    public int Current { [System.Runtime.CompilerServices.RequiresUnsafe] get => 0; }
                }
                """,
            caller: """
                foreach (var x in new C()) { }
                unsafe { foreach (var x in new C()) { } }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.get_Current"],
            expectedSafeSymbols: ["C", "C.Current"],
            expectedDiagnostics:
            [
                // (1,1): error CS9362: 'C.Current.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // foreach (var x in new C()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "foreach").WithArguments("C.Current.get").WithLocation(1, 1),
            ]);
    }
 
    [Fact]
    public void Member_Current_Setter()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public C GetEnumerator() => this;
                    public bool MoveNext() => false;
                    public int Current { get => 0; [System.Runtime.CompilerServices.RequiresUnsafe] set { } }
                }
                """,
            caller: """
                foreach (var x in new C()) { }
                unsafe { foreach (var x in new C()) { } }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.set_Current"],
            expectedSafeSymbols: ["C", "C.Current", "C.get_Current"],
            expectedDiagnostics: []);
    }
 
    [Fact]
    public void Member_Dispose_Class()
    {
        CreateCompilation(["""
            public class C : System.IDisposable
            {
                public C GetEnumerator() => this;
                public bool MoveNext() => false;
                public int Current => 0;
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public void Dispose() { }
            }
            """, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (7,17): error CS9365: Unsafe member 'C.Dispose()' cannot implicitly implement safe member 'IDisposable.Dispose()'
            //     public unsafe void Dispose() { }
            Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "Dispose").WithArguments("C.Dispose()", "System.IDisposable.Dispose()").WithLocation(7, 17));
    }
 
    [Fact]
    public void Member_Dispose_Interface()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C : System.IDisposable
                {
                    public C GetEnumerator() => this;
                    public bool MoveNext() => false;
                    public int Current => 0;
                    public void Dispose() { }
                }
 
                namespace System
                {
                    public class Object;
                    public class ValueType;
                    public class Attribute;
                    public struct Void;
                    public struct Int32;
                    public struct Boolean;
                    public class AttributeUsageAttribute
                    {
                        public AttributeUsageAttribute(AttributeTargets t) { }
                        public bool AllowMultiple { get; set; }
                        public bool Inherited { get; set; }
                    }
                    public class String;
                    public class Enum;
                    public enum AttributeTargets;
                    public interface IDisposable
                    {
                        [System.Runtime.CompilerServices.RequiresUnsafe]
                        void Dispose();
                    }
                }
 
                namespace System.Runtime.CompilerServices
                {
                    public class CompilerGeneratedAttribute;
                    public class RequiresUnsafeAttribute : Attribute;
                }
 
                namespace System.Collections
                {
                    public interface IEnumerable;
                }
 
                namespace System.Collections.Generic
                {
                    public interface IEnumerable<T> : IEnumerable;
                    public class List<T> : IEnumerable<T>
                    {
                        public void Add(T element) { }
                    }
                }
                """,
            caller: """
                foreach (var x in new C()) { }
                using (var c = new C()) { }
                System.Collections.Generic.List<int> l = [.. new C()];
                unsafe { foreach (var x in new C()) { } }
                unsafe { using (var c = new C()) { } }
                unsafe { System.Collections.Generic.List<int> l2 = [.. new C()]; }
                """,
            targetFramework: TargetFramework.Empty,
            optionsDll: TestOptions.UnsafeDebugDll
                // warning CS8021: No value for RuntimeMetadataVersion found
                .WithSpecificDiagnosticOptions(GetIdForErrorCode(ErrorCode.WRN_NoRuntimeMetadataVersion), ReportDiagnostic.Suppress),
            expectedUnsafeSymbols: ["System.IDisposable.Dispose"],
            expectedSafeSymbols: ["C", "C.Dispose", "System.IDisposable"],
            verify: Verification.FailsPEVerify,
            expectedDiagnostics:
            [
                // (1,1): error CS9362: 'IDisposable.Dispose()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // foreach (var x in new C()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "foreach").WithArguments("System.IDisposable.Dispose()").WithLocation(1, 1),
                // (2,8): error CS9362: 'IDisposable.Dispose()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // using (var c = new C()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "var c = new C()").WithArguments("System.IDisposable.Dispose()").WithLocation(2, 8),
                // (3,43): error CS9362: 'IDisposable.Dispose()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // System.Collections.Generic.List<int> l = [.. new C()];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "..").WithArguments("System.IDisposable.Dispose()").WithLocation(3, 43),
            ]);
    }
 
    [Fact]
    public void Member_Dispose_RefStruct()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public ref struct S
                {
                    public S GetEnumerator() => this;
                    public bool MoveNext() => false;
                    public int Current => 0;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void Dispose() { }
                }
                """,
            caller: """
                foreach (var x in new S()) { }
                using (var s = new S()) { }
                unsafe { foreach (var y in new S()) { } }
                unsafe { using (var s = new S()) { } }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["S.Dispose"],
            expectedSafeSymbols: ["S"],
            expectedDiagnostics:
            [
                // (1,1): error CS9362: 'S.Dispose()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // foreach (var x in new S()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "foreach (var x in new S()) { }").WithArguments("S.Dispose()").WithLocation(1, 1),
                // (2,8): error CS9362: 'S.Dispose()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // using (var s = new S()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "var s = new S()").WithArguments("S.Dispose()").WithLocation(2, 8),
            ]);
    }
 
    [Fact]
    public void Member_DisposeAsync()
    {
        CompileAndVerifyUnsafe(
            lib: """
                using System.Threading.Tasks;
                public class C
                {
                    public C GetAsyncEnumerator() => this;
                    public Task<bool> MoveNextAsync() => null;
                    public int Current => 0;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public Task DisposeAsync() => null;
                }
                """,
            caller: """
                await foreach (var x in new C()) { }
                await using (var c = new C()) { }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.DisposeAsync"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,1): error CS9362: 'C.DisposeAsync()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // await foreach (var x in new C()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "await foreach (var x in new C()) { }").WithArguments("C.DisposeAsync()").WithLocation(1, 1),
                // (2,14): error CS9362: 'C.DisposeAsync()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // await using (var c = new C()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "var c = new C()").WithArguments("C.DisposeAsync()").WithLocation(2, 14),
            ]);
    }
 
    [Fact]
    public void Member_GetPinnableReference()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C1 { public ref int GetPinnableReference() => throw null; }
                public class C2 { [System.Runtime.CompilerServices.RequiresUnsafe] public ref int GetPinnableReference() => throw null; }
                """,
            caller: """
                fixed (int* p = new C1()) { }
                fixed (int* p = new C2()) { }
                unsafe { fixed (int* p = new C2()) { } }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C2.GetPinnableReference"],
            expectedSafeSymbols: ["C1", "C1.GetPinnableReference", "C2"],
            expectedDiagnostics:
            [
                // (2,17): error CS9362: 'C2.GetPinnableReference()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // fixed (int* p = new C2()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C2()").WithArguments("C2.GetPinnableReference()").WithLocation(2, 17),
            ],
            expectedDiagnosticsForLegacyCaller:
            [
                // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                // fixed (int* p = new C1()) { }
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "fixed (int* p = new C1()) { }").WithLocation(1, 1),
                // (1,8): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                // fixed (int* p = new C1()) { }
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 8),
                // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                // fixed (int* p = new C2()) { }
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "fixed (int* p = new C2()) { }").WithLocation(2, 1),
                // (2,8): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
                // fixed (int* p = new C2()) { }
                Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(2, 8),
            ]);
    }
 
    [Fact]
    public void Member_Deconstruct()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void Deconstruct(out int x, out int y) { x = y = 0; }
                }
                """,
            caller: """
                var (x, y) = new C();
                unsafe { var (a, b) = new C(); }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.Deconstruct"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,14): error CS9362: 'C.Deconstruct(out int, out int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var (x, y) = new C();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C()").WithArguments("C.Deconstruct(out int, out int)").WithLocation(1, 14),
            ]);
    }
 
    [Fact]
    public void Member_LockObject()
    {
        CompileAndVerifyUnsafe(
            lib: """
                namespace System.Threading;
                public class Lock
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public Scope EnterScope() => new();
                    public ref struct Scope
                    {
                        [System.Runtime.CompilerServices.RequiresUnsafe]
                        public void Dispose() { }
                    }
                }
                """,
            caller: """
                lock (new System.Threading.Lock()) { }
                unsafe { lock (new System.Threading.Lock()) { } }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["System.Threading.Lock.EnterScope", "System.Threading.Lock.Scope.Dispose"],
            expectedSafeSymbols: ["System.Threading.Lock", "System.Threading.Lock.Scope"],
            expectedDiagnostics:
            [
                // (1,7): error CS9362: 'Lock.EnterScope()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // lock (new System.Threading.Lock()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new System.Threading.Lock()").WithArguments("System.Threading.Lock.EnterScope()").WithLocation(1, 7),
                // (1,7): error CS9362: 'Lock.Scope.Dispose()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // lock (new System.Threading.Lock()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new System.Threading.Lock()").WithArguments("System.Threading.Lock.Scope.Dispose()").WithLocation(1, 7),
            ]);
    }
 
    [Fact]
    public void Member_ITuple()
    {
        CompileAndVerifyUnsafe(
            lib: """
                namespace System.Runtime.CompilerServices;
                public interface ITuple
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    int Length { get; }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    object this[int index] { get; }
                }
                """,
            caller: """
                object o = null;
                _ = o is (int x, string y);
                unsafe { _ = o is (int a, string b); }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["System.Runtime.CompilerServices.ITuple.Length", "System.Runtime.CompilerServices.ITuple.get_Length", "System.Runtime.CompilerServices.ITuple.this[]", "System.Runtime.CompilerServices.ITuple.get_Item"],
            expectedSafeSymbols: ["System.Runtime.CompilerServices.ITuple"],
            expectedDiagnostics:
            [
                // (2,10): error CS9362: 'ITuple.Length.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = o is (int x, string y);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "(int x, string y)").WithArguments("System.Runtime.CompilerServices.ITuple.Length.get").WithLocation(2, 10),
                // (2,10): error CS9362: 'ITuple.this[int].get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = o is (int x, string y);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "(int x, string y)").WithArguments("System.Runtime.CompilerServices.ITuple.this[int].get").WithLocation(2, 10),
            ]);
    }
 
    [Fact]
    public void Member_InterpolatedStringHandler()
    {
        CompileAndVerifyUnsafe(
            lib: """
                [System.Runtime.CompilerServices.InterpolatedStringHandler]
                public struct C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public C(int literalLength, int formattedCount) { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void AppendLiteral(string s) { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void AppendFormatted<T>(T t) { }
                }
                """,
            caller: """
                log($"a{0}");
                unsafe { log($"a{0}"); };
                void log(C c) { }
                """,
            additionalSources: [InterpolatedStringHandlerAttribute, RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: [Overload("C..ctor", parameterCount: 2), "C.AppendLiteral", "C.AppendFormatted"],
            expectedSafeSymbols: ["C", Overload("C..ctor", parameterCount: 0)],
            expectedDiagnostics:
            [
                // (1,7): error CS9362: 'C.AppendLiteral(string)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // log($"a{0}");
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "a").WithArguments("C.AppendLiteral(string)").WithLocation(1, 7),
                // (1,8): error CS9362: 'C.AppendFormatted<int>(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // log($"a{0}");
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "{0}").WithArguments("C.AppendFormatted<int>(int)").WithLocation(1, 8),
                // (1,5): error CS9362: 'C.C(int, int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // log($"a{0}");
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, @"$""a{0}""").WithArguments("C.C(int, int)").WithLocation(1, 5),
            ]);
    }
 
    [Theory, CombinatorialData]
    public void Member_Interceptor(
        [CombinatorialValues("[System.Runtime.CompilerServices.RequiresUnsafe]", "")] string unsafe1,
        [CombinatorialValues("[System.Runtime.CompilerServices.RequiresUnsafe]", "")] string unsafe2)
    {
        var source = ($$"""
            C.M();
 
            class C
            {
                {{unsafe1}}
                public static void M() { }
            }
            """, "Program.cs");
 
        var comp = CreateCompilation(source);
        var tree = comp.SyntaxTrees.Single();
        var model = comp.GetSemanticModel(tree);
        var interceptableLocation = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Select(node => model.GetInterceptableLocation(node)).Single()!;
 
        var interceptor = ($$"""
            class D
            {
                {{interceptableLocation.GetInterceptsLocationAttributeSyntax()}}
                {{unsafe2}}
                public static void M() => System.Console.Write(1);
            }
            """, "Interceptor.cs");
 
        CreateCompilation([source, interceptor, (TestSources.InterceptsLocationAttribute, "Attribute.cs"), RequiresUnsafeAttributeDefinition],
            parseOptions: TestOptions.RegularPreview.WithFeature(Feature.InterceptorsNamespaces, "global"),
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(unsafe1.Length > 0
            ? [
                // Program.cs(1,1): error CS9362: 'C.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C.M();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "C.M()").WithArguments("C.M()").WithLocation(1, 1),
            ]
            : []);
    }
 
    [Fact]
    public void Member_Iterator()
    {
        var lib = """
            using System.Collections.Generic;
 
            public static class C
            {
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public static IEnumerable<int> M()
                {
                    yield return 1;
                }
            }
            """;
 
        CompileAndVerifyUnsafe(
            lib: lib,
            caller: """
                foreach (var x in C.M()) { }
                unsafe { foreach (var y in C.M()) { } }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.M"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,19): error CS9362: 'C.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // foreach (var x in C.M()) { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "C.M()").WithArguments("C.M()").WithLocation(1, 19),
            ]);
 
        // Test symbols that are only in PE image (hence cannot test them via the helper above).
        var libRef = CreateCompilation(
            [lib, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules().WithMetadataImportOptions(MetadataImportOptions.All))
            .EmitToImageReference();
        var libAssemblySymbol = CreateCompilation("", [libRef]).GetReferencedAssemblySymbol(libRef);
        VerifyRequiresUnsafeAttribute(
            libAssemblySymbol.Modules.Single(),
            expectedUnsafeSymbols: ["C.M"],
            expectedSafeSymbols: ["C", "C.<M>d__0", "C.<M>d__0.MoveNext"]);
    }
 
    [Fact]
    public void Member_LocalFunction()
    {
        var source = """
            M1();
            M2();
            unsafe { M1(); }
            [System.Runtime.CompilerServices.RequiresUnsafe]
            static void M1() { }
            static void M2() { }
            """;
        CreateCompilation([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS9362: 'M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // M1();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "M1()").WithArguments("M1()").WithLocation(1, 1));
    }
 
    [Fact]
    public void Member_Lambda()
    {
        var source = """
            var lam = [System.Runtime.CompilerServices.RequiresUnsafe] () => { };
            lam();
            """;
        CreateCompilation([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,12): error CS9367: RequiresUnsafeAttribute cannot be applied to this symbol.
            // var lam = [System.Runtime.CompilerServices.RequiresUnsafe] () => { };
            Diagnostic(ErrorCode.ERR_RequiresUnsafeAttributeUnsupportedMemberTarget, "System.Runtime.CompilerServices.RequiresUnsafe").WithLocation(1, 12));
    }
 
    [Fact]
    public void Member_Lambda_InUnsafeContext()
    {
        var source = """
            unsafe
            {
                D lam = () => { };
            }
 
            delegate void D();
            """;
        var metadata = CreateCompilation(source,
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics()
            .EmitToImageReference();
        var assemblySymbol = CreateCompilation("", [metadata],
            options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.All))
            .GetReferencedAssemblySymbol(metadata);
        VerifyRequiresUnsafeAttribute(
            assemblySymbol.Modules.Single(),
            expectedUnsafeSymbols: [],
            expectedSafeSymbols:
            [
                "Program",
                "Program.<Main>$",
                "Program.<>c",
                "Program.<>c.<<Main>$>b__0_0",
                "D",
                "D..ctor",
                "D.Invoke",
                "D.BeginInvoke",
                "D.EndInvoke",
            ]);
    }
 
    [Fact]
    public void Member_Property()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public int P1 { get; set; }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int P2 { get; set; }
                }
                """,
            caller: """
                var c = new C();
                c.P1 = c.P1 + 123;
                c.P2 = c.P2 + 123;
                unsafe { c.P2 = c.P2 + 123; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.P2", "C.get_P2", "C.set_P2"],
            expectedSafeSymbols: ["C.P1", "C.get_P1", "C.set_P1"],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'C.P2.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P2 = c.P2 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C.P2.set").WithLocation(3, 1),
                // (3,8): error CS9362: 'C.P2.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P2 = c.P2 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C.P2.get").WithLocation(3, 8)
            ]);
    }
 
    [Fact]
    public void Member_Property_CompoundAssignment()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int P { get; set; }
                }
                """,
            caller: """
                var c = new C();
                c.P += 123;
                unsafe { c.P += 123; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.P", "C.get_P", "C.set_P"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (2,1): error CS9362: 'C.P.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P += 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P").WithArguments("C.P.set").WithLocation(2, 1),
                // (2,1): error CS9362: 'C.P.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P += 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P").WithArguments("C.P.get").WithLocation(2, 1),
            ]);
    }
 
    [Fact]
    public void Member_Property_ObjectInitializer()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public C P1 { get; set; }
                    public C P2 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                    public C P3 { get; [System.Runtime.CompilerServices.RequiresUnsafe] set; }
                    public C P4 { get; set; }
                }
                """,
            caller: """
                _ = new C
                {
                    P1 = null,
                    P2 = null,
                    P3 = null,
                    P4 = null,
                };
                _ = new C
                {
                    P1 = { },
                    P2 = { },
                    P3 = { },
                    P4 = { },
                };
                unsafe { _ = new C { P1 = null, P2 = null, P3 = null, P4 = null }; }
                unsafe { _ = new C { P1 = { }, P2 = { }, P3 = { }, P4 = { } }; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.P1", "C.get_P1", "C.set_P1", "C.get_P2", "C.set_P3"],
            expectedSafeSymbols: ["C", "C.P2", "C.set_P2", "C.P3", "C.get_P3", "C.P4", "C.get_P4", "C.set_P4"],
            expectedDiagnostics:
            [
                // (3,5): error CS9362: 'C.P1.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     P1 = null,
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "P1").WithArguments("C.P1.set").WithLocation(3, 5),
                // (5,5): error CS9362: 'C.P3.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     P3 = null,
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "P3").WithArguments("C.P3.set").WithLocation(5, 5),
                // (10,5): error CS9362: 'C.P1.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     P1 = { },
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "P1").WithArguments("C.P1.get").WithLocation(10, 5),
                // (11,5): error CS9362: 'C.P2.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     P2 = { },
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "P2").WithArguments("C.P2.get").WithLocation(11, 5),
            ]);
    }
 
    [Fact]
    public void Member_Property_Pattern()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int this[int i] => 0;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int Length => 0;
                }
                """,
            caller: """
                var c = new C();
                _ = c is { Length: 0 };
                _ = c is [];
                unsafe { _ = c is { Length: 0 }; }
                unsafe { _ = c is []; }
                """,
            additionalSources: [TestSources.Index, RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.this[]", "C.get_Item", "C.Length", "C.get_Length"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                 // (2,12): error CS9362: 'C.Length.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = c is { Length: 0 };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "Length:").WithArguments("C.Length.get").WithLocation(2, 12),
                // (3,10): error CS9362: 'C.Length.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = c is [];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "[]").WithArguments("C.Length.get").WithLocation(3, 10),
                // (3,10): error CS9362: 'C.Length.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = c is [];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "[]").WithArguments("C.Length.get").WithLocation(3, 10),
                // (3,10): error CS9362: 'C.this[int].get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = c is [];
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "[]").WithArguments("C.this[int].get").WithLocation(3, 10),
            ]);
    }
 
    [Fact]
    public void Member_Property_Extension()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public static class E
                {
                    extension(int x)
                    {
                        public int P1 { get => x; set { } }
                        [System.Runtime.CompilerServices.RequiresUnsafe]
                        public int P2 { get => x; set { } }
                    }
                }
                """,
            caller: """
                var x = 111;
                x.P1 = x.P1 + 222;
                x.P2 = x.P2 + 333;
                E.get_P1(x); E.set_P1(x, 0);
                E.get_P2(x); E.set_P2(x, 0);
                unsafe { x.P2 = x.P2 + 444; }
                unsafe { E.get_P2(x); E.set_P2(x, 0); }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: [ExtensionMember("E", "P2"), "E.get_P2", ExtensionMember("E", "get_P2"), "E.set_P2", ExtensionMember("E", "set_P2")],
            expectedSafeSymbols: [ExtensionMember("E", "P1"), "E.get_P1", ExtensionMember("E", "get_P1"), "E.set_P1", ExtensionMember("E", "set_P1")],
            expectedNoAttributeInSource: ["E.get_P2", "E.set_P2"],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'E.extension(int).P2.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // x.P2 = x.P2 + 333;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "x.P2").WithArguments("E.extension(int).P2.set").WithLocation(3, 1),
                // (3,8): error CS9362: 'E.extension(int).P2.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // x.P2 = x.P2 + 333;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "x.P2").WithArguments("E.extension(int).P2.get").WithLocation(3, 8),
                // (5,1): error CS9362: 'E.get_P2(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // E.get_P2(x); E.set_P2(x, 0);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "E.get_P2(x)").WithArguments("E.get_P2(int)").WithLocation(5, 1),
                // (5,14): error CS9362: 'E.set_P2(int, int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // E.get_P2(x); E.set_P2(x, 0);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "E.set_P2(x, 0)").WithArguments("E.set_P2(int, int)").WithLocation(5, 14),
            ]);
    }
 
    [Fact]
    public void Member_Property_Record()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public record C(int P1, int P2)
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int P2 { get; set; } = P2;
                }
                """,
            caller: """
                var c = new C(1, 2);
                c.P2 = c.P1 + c.P2;
                unsafe { c.P2 = c.P1 + c.P2; }
                """,
            additionalSources: [IsExternalInitTypeDefinition, RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["C.P2", "C.get_P2", "C.set_P2"],
            expectedSafeSymbols: ["C.P1", "C.get_P1", "C.set_P1"],
            expectedDiagnostics:
            [
                // (2,1): error CS9362: 'C.P2.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P2 = c.P1 + c.P2;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C.P2.set").WithLocation(2, 1),
                // (2,15): error CS9362: 'C.P2.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P2 = c.P1 + c.P2;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C.P2.get").WithLocation(2, 15),
            ]);
    }
 
    [Fact]
    public void Member_Property_Accessors()
    {
        var lib = """
            public class C
            {
                public int P1 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                public int P2 { get; [System.Runtime.CompilerServices.RequiresUnsafe] set; }
            }
            """;
 
        CompileAndVerifyUnsafe(
            lib: lib,
            caller: """
                var c = new C();
                c.P1 = c.P1 + 123;
                c.P2 = c.P2 + 123;
                unsafe { c.P1 = c.P1 + 123; }
                unsafe { c.P2 = c.P2 + 123; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.get_P1", "C.set_P2"],
            expectedSafeSymbols: ["C.P1", "C.P2", "C.get_P2", "C.set_P1"],
            expectedDiagnostics:
            [
                // (2,8): error CS9362: 'C.P1.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P1 = c.P1 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P1").WithArguments("C.P1.get").WithLocation(2, 8),
                // (3,1): error CS9362: 'C.P2.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P2 = c.P2 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C.P2.set").WithLocation(3, 1),
            ]);
 
        var expectedDiagnostics = new[]
        {
            // (3,22): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     public int P1 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "System.Runtime.CompilerServices.RequiresUnsafe").WithLocation(3, 22),
            // (4,27): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     public int P2 { get; [System.Runtime.CompilerServices.RequiresUnsafe] set; }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "System.Runtime.CompilerServices.RequiresUnsafe").WithLocation(4, 27),
        };
 
        CreateCompilation([lib, RequiresUnsafeAttributeDefinition], parseOptions: TestOptions.Regular14).VerifyEmitDiagnostics(expectedDiagnostics);
        CreateCompilation([lib, RequiresUnsafeAttributeDefinition], parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics);
        CreateCompilation([lib, RequiresUnsafeAttributeDefinition], parseOptions: TestOptions.RegularPreview).VerifyEmitDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Member_Property_Attribute()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class A : System.Attribute
                {
                    public int P1 { get; set; }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int P2 { get; set; }
                    public int P3 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                    public int P4 { get; [System.Runtime.CompilerServices.RequiresUnsafe] set; }
                    public unsafe int F;
                }
                """,
            caller: """
                var c = new C1();
                [A(P1 = 0, P2 = 0, P3 = 0, P4 = 0, F = 0)] class C1;
                [A(P1 = 0, P2 = 0, P3 = 0, P4 = 0, F = 0)] unsafe class C2;
                partial class C3
                {
                    [A(P1 = 0, P2 = 0, P3 = 0, P4 = 0, F = 0)] void M1() { }
                }
                unsafe partial class C3
                {
                    [A(P1 = 0, P2 = 0, P3 = 0, P4 = 0, F = 0)] void M2() { }
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["A.P2", "A.get_P2", "A.set_P2", "A.get_P3", "A.set_P4"],
            expectedSafeSymbols: ["A.P1", "A.get_P1", "A.set_P1", "A.set_P3", "A.get_P4", "A.F"],
            expectedDiagnostics:
            [
                // (2,12): error CS9362: 'A.P2.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // [A(P1 = 0, P2 = 0, P3 = 0, P4 = 0, F = 0)] class C1;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "P2 = 0").WithArguments("A.P2.set").WithLocation(2, 12),
                // (2,28): error CS9362: 'A.P4.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // [A(P1 = 0, P2 = 0, P3 = 0, P4 = 0, F = 0)] class C1;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "P4 = 0").WithArguments("A.P4.set").WithLocation(2, 28),
                // (6,16): error CS9362: 'A.P2.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     [A(P1 = 0, P2 = 0, P3 = 0, P4 = 0, F = 0)] void M1() { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "P2 = 0").WithArguments("A.P2.set").WithLocation(6, 16),
                // (6,32): error CS9362: 'A.P4.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     [A(P1 = 0, P2 = 0, P3 = 0, P4 = 0, F = 0)] void M1() { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "P4 = 0").WithArguments("A.P4.set").WithLocation(6, 32),
            ]);
    }
 
    [Fact]
    public void Member_Property_Override()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class B
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public virtual int P1 { get; set; }
                    public virtual int P2 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                    public virtual int P3 { get; set; }
                }
                """,
            caller: """
                var c = new C1();
                c.P1 = c.P1 + 123;
                c.P2 = c.P2 + 123;
                c.P3 = c.P3 + 123;
 
                class C1 : B
                {
                    public override int P1 { get; set; }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override int P2 { get; set; }
                    public override int P3 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                }
 
                class C2 : B
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override int P1 { get; set; }
                    public override int P2 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override int P3 { get; set; }
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["B.P1", "B.get_P1", "B.set_P1", "B.get_P2"],
            expectedSafeSymbols: ["B.P2", "B.set_P2", "B.P3", "B.get_P3", "B.set_P3"],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'C1.P2.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P2 = c.P2 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C1.P2.set").WithLocation(3, 1),
                // (3,8): error CS9362: 'C1.P2.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P2 = c.P2 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C1.P2.get").WithLocation(3, 8),
                // (4,8): error CS9362: 'C1.P3.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P3 = c.P3 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P3").WithArguments("C1.P3.get").WithLocation(4, 8),
                // (10,35): error CS9364: Unsafe member 'C1.P2.set' cannot override safe member 'B.P2.set'
                //     public override int P2 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "set").WithArguments("C1.P2.set", "B.P2.set").WithLocation(10, 35),
                // (11,79): error CS9364: Unsafe member 'C1.P3.get' cannot override safe member 'B.P3.get'
                //     public override int P3 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "get").WithArguments("C1.P3.get", "B.P3.get").WithLocation(11, 79),
                // (20,30): error CS9364: Unsafe member 'C2.P3.get' cannot override safe member 'B.P3.get'
                //     public override int P3 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "get").WithArguments("C2.P3.get", "B.P3.get").WithLocation(20, 30),
                // (20,35): error CS9364: Unsafe member 'C2.P3.set' cannot override safe member 'B.P3.set'
                //     public override int P3 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "set").WithArguments("C2.P3.set", "B.P3.set").WithLocation(20, 35),
            ],
            expectedDiagnosticsWhenReferencingLegacyLib:
            [
                // (3,1): error CS9362: 'C1.P2.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P2 = c.P2 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C1.P2.set").WithLocation(3, 1),
                // (3,8): error CS9362: 'C1.P2.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P2 = c.P2 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C1.P2.get").WithLocation(3, 8),
                // (4,8): error CS9362: 'C1.P3.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P3 = c.P3 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P3").WithArguments("C1.P3.get").WithLocation(4, 8),
                // (10,30): error CS9364: Unsafe member 'C1.P2.get' cannot override safe member 'B.P2.get'
                //     public override int P2 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "get").WithArguments("C1.P2.get", "B.P2.get").WithLocation(10, 30),
                // (10,35): error CS9364: Unsafe member 'C1.P2.set' cannot override safe member 'B.P2.set'
                //     public override int P2 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "set").WithArguments("C1.P2.set", "B.P2.set").WithLocation(10, 35),
                // (11,79): error CS9364: Unsafe member 'C1.P3.get' cannot override safe member 'B.P3.get'
                //     public override int P3 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "get").WithArguments("C1.P3.get", "B.P3.get").WithLocation(11, 79),
                // (17,30): error CS9364: Unsafe member 'C2.P1.get' cannot override safe member 'B.P1.get'
                //     public override int P1 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "get").WithArguments("C2.P1.get", "B.P1.get").WithLocation(17, 30),
                // (17,35): error CS9364: Unsafe member 'C2.P1.set' cannot override safe member 'B.P1.set'
                //     public override int P1 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "set").WithArguments("C2.P1.set", "B.P1.set").WithLocation(17, 35),
                // (18,79): error CS9364: Unsafe member 'C2.P2.get' cannot override safe member 'B.P2.get'
                //     public override int P2 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "get").WithArguments("C2.P2.get", "B.P2.get").WithLocation(18, 79),
                // (20,30): error CS9364: Unsafe member 'C2.P3.get' cannot override safe member 'B.P3.get'
                //     public override int P3 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "get").WithArguments("C2.P3.get", "B.P3.get").WithLocation(20, 30),
                // (20,35): error CS9364: Unsafe member 'C2.P3.set' cannot override safe member 'B.P3.set'
                //     public override int P3 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "set").WithArguments("C2.P3.set", "B.P3.set").WithLocation(20, 35),
            ]);
    }
 
    [Fact]
    public void Member_Property_Implementation()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public interface I
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    int P1 { get; set; }
                    int P2 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                    int P3 { get; set; }
                }
                """,
            caller: """
                I i = new C1();
                i.P1 = i.P1 + 123;
                i.P2 = i.P2 + 123;
                i.P3 = i.P3 + 123;
 
                class C1 : I
                {
                    public int P1 { get; set; }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int P2 { get; set; }
                    public int P3 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                }
 
                class C2 : I
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int P1 { get; set; }
                    public int P2 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int P3 { get; set; }
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["I.P1", "I.get_P1", "I.set_P1", "I.get_P2"],
            expectedSafeSymbols: ["I.P2", "I.set_P2", "I.P3", "I.get_P3", "I.set_P3"],
            expectedDiagnostics:
            [
                // (2,1): error CS9362: 'I.P1.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // i.P1 = i.P1 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "i.P1").WithArguments("I.P1.set").WithLocation(2, 1),
                // (2,8): error CS9362: 'I.P1.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // i.P1 = i.P1 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "i.P1").WithArguments("I.P1.get").WithLocation(2, 8),
                // (3,8): error CS9362: 'I.P2.get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // i.P2 = i.P2 + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "i.P2").WithArguments("I.P2.get").WithLocation(3, 8),
                // (10,26): error CS9365: Unsafe member 'C1.P2.set' cannot implicitly implement safe member 'I.P2.set'
                //     public int P2 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "set").WithArguments("C1.P2.set", "I.P2.set").WithLocation(10, 26),
                // (11,70): error CS9365: Unsafe member 'C1.P3.get' cannot implicitly implement safe member 'I.P3.get'
                //     public int P3 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "get").WithArguments("C1.P3.get", "I.P3.get").WithLocation(11, 70),
                // (20,21): error CS9365: Unsafe member 'C2.P3.get' cannot implicitly implement safe member 'I.P3.get'
                //     public int P3 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "get").WithArguments("C2.P3.get", "I.P3.get").WithLocation(20, 21),
                // (20,26): error CS9365: Unsafe member 'C2.P3.set' cannot implicitly implement safe member 'I.P3.set'
                //     public int P3 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "set").WithArguments("C2.P3.set", "I.P3.set").WithLocation(20, 26),
            ],
            expectedDiagnosticsWhenReferencingLegacyLib:
            [
                // (10,21): error CS9365: Unsafe member 'C1.P2.get' cannot implicitly implement safe member 'I.P2.get'
                //     public int P2 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "get").WithArguments("C1.P2.get", "I.P2.get").WithLocation(10, 21),
                // (10,26): error CS9365: Unsafe member 'C1.P2.set' cannot implicitly implement safe member 'I.P2.set'
                //     public int P2 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "set").WithArguments("C1.P2.set", "I.P2.set").WithLocation(10, 26),
                // (11,70): error CS9365: Unsafe member 'C1.P3.get' cannot implicitly implement safe member 'I.P3.get'
                //     public int P3 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "get").WithArguments("C1.P3.get", "I.P3.get").WithLocation(11, 70),
                // (17,21): error CS9365: Unsafe member 'C2.P1.get' cannot implicitly implement safe member 'I.P1.get'
                //     public int P1 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "get").WithArguments("C2.P1.get", "I.P1.get").WithLocation(17, 21),
                // (17,26): error CS9365: Unsafe member 'C2.P1.set' cannot implicitly implement safe member 'I.P1.set'
                //     public int P1 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "set").WithArguments("C2.P1.set", "I.P1.set").WithLocation(17, 26),
                // (18,70): error CS9365: Unsafe member 'C2.P2.get' cannot implicitly implement safe member 'I.P2.get'
                //     public int P2 { [System.Runtime.CompilerServices.RequiresUnsafe] get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "get").WithArguments("C2.P2.get", "I.P2.get").WithLocation(18, 70),
                // (20,21): error CS9365: Unsafe member 'C2.P3.get' cannot implicitly implement safe member 'I.P3.get'
                //     public int P3 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "get").WithArguments("C2.P3.get", "I.P3.get").WithLocation(20, 21),
                // (20,26): error CS9365: Unsafe member 'C2.P3.set' cannot implicitly implement safe member 'I.P3.set'
                //     public int P3 { get; set; }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "set").WithArguments("C2.P3.set", "I.P3.set").WithLocation(20, 26),
            ]);
    }
 
    [Fact]
    public void Member_Indexer()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C1
                {
                    public int this[int i] { get => i; set { } }
                }
                public class C2
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int this[int i] { get => i; set { } }
                }
                """,
            caller: """
                var c1 = new C1();
                c1[0] = c1[0] + 123;
                var c2 = new C2();
                c2[0] = c2[0] + 123;
                unsafe { c2[0] = c2[0] + 123; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C2.this[]", "C2.get_Item", "C2.set_Item"],
            expectedSafeSymbols: ["C1.this[]", "C1.get_Item", "C1.set_Item"],
            expectedDiagnostics:
            [
                // (4,1): error CS9362: 'C2.this[int].set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c2[0] = c2[0] + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c2[0]").WithArguments("C2.this[int].set").WithLocation(4, 1),
                // (4,9): error CS9362: 'C2.this[int].get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c2[0] = c2[0] + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c2[0]").WithArguments("C2.this[int].get").WithLocation(4, 9),
            ]);
    }
 
    [Fact]
    public void Member_Indexer_CompoundAssignment()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public int this[int i] { get => i; set { } }
                }
                """,
            caller: """
                var c = new C();
                c[0] += 123;
                unsafe { c[0] += 123; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.this[]", "C.get_Item", "C.set_Item"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (2,1): error CS9362: 'C.this[int].set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c[0] += 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c[0]").WithArguments("C.this[int].set").WithLocation(2, 1),
                // (2,1): error CS9362: 'C.this[int].get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c[0] += 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c[0]").WithArguments("C.this[int].get").WithLocation(2, 1),
            ]);
    }
 
    [Fact]
    public void Member_Indexer_ObjectInitializer()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C1 { [System.Runtime.CompilerServices.RequiresUnsafe] public object this[int i] { get => null; set { } } }
                public class C2 { public object this[int i] { [System.Runtime.CompilerServices.RequiresUnsafe] get => null; set { } } }
                public class C3 { public object this[int i] { get => null; [System.Runtime.CompilerServices.RequiresUnsafe] set { } } }
                public class C4 { public object this[int i] { get => null; set { } } }
                """,
            caller: """
                _ = new C1 { [0] = null, [0] = { } };
                _ = new C2 { [0] = null, [0] = { } };
                _ = new C3 { [0] = null, [0] = { } };
                _ = new C4 { [0] = null, [0] = { } };
                unsafe { _ = new C1 { [0] = null, [0] = { } }; }
                unsafe { _ = new C2 { [0] = null, [0] = { } }; }
                unsafe { _ = new C3 { [0] = null, [0] = { } }; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C1.this[]", "C1.get_Item", "C1.set_Item", "C2.get_Item", "C3.set_Item"],
            expectedSafeSymbols: ["C1", "C2", "C2.this[]", "C2.set_Item", "C3", "C3.this[]", "C3.get_Item", "C4", "C4.this[]", "C4.get_Item", "C4.set_Item"],
            expectedDiagnostics:
            [
                // (1,14): error CS9362: 'C1.this[int].set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = new C1 { [0] = null, [0] = { } };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "[0]").WithArguments("C1.this[int].set").WithLocation(1, 14),
                // (1,26): error CS9362: 'C1.this[int].get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = new C1 { [0] = null, [0] = { } };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "[0]").WithArguments("C1.this[int].get").WithLocation(1, 26),
                // (2,26): error CS9362: 'C2.this[int].get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = new C2 { [0] = null, [0] = { } };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "[0]").WithArguments("C2.this[int].get").WithLocation(2, 26),
                // (3,14): error CS9362: 'C3.this[int].set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = new C3 { [0] = null, [0] = { } };
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "[0]").WithArguments("C3.this[int].set").WithLocation(3, 14),
            ]);
    }
 
    [Fact]
    public void Member_Indexer_Accessors()
    {
        var lib = """
            public class C1
            {
                public int this[int i] { [System.Runtime.CompilerServices.RequiresUnsafe] get => i; set { } }
            }
            public class C2
            {
                public int this[int i] { get => i; [System.Runtime.CompilerServices.RequiresUnsafe] set { } }
            }
            """;
 
        CompileAndVerifyUnsafe(
            lib: lib,
            caller: """
                var c1 = new C1();
                c1[0] = c1[0] + 123;
                var c2 = new C2();
                c2[0] = c2[0] + 123;
                unsafe { c1[0] = c1[0] + 123; }
                unsafe { c2[0] = c2[0] + 123; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C1.get_Item", "C2.set_Item"],
            expectedSafeSymbols: ["C1.this[]", "C2.this[]", "C2.get_Item", "C1.set_Item"],
            expectedDiagnostics:
            [
                // (2,9): error CS9362: 'C1.this[int].get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c1[0] = c1[0] + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c1[0]").WithArguments("C1.this[int].get").WithLocation(2, 9),
                // (4,1): error CS9362: 'C2.this[int].set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c2[0] = c2[0] + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c2[0]").WithArguments("C2.this[int].set").WithLocation(4, 1),
            ]);
 
        var expectedDiagnostics = new[]
        {
            // (3,31): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     public int this[int i] { [System.Runtime.CompilerServices.RequiresUnsafe] get => i; set { } }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "System.Runtime.CompilerServices.RequiresUnsafe").WithLocation(3, 31),
            // (7,41): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     public int this[int i] { get => i; [System.Runtime.CompilerServices.RequiresUnsafe] set { } }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "System.Runtime.CompilerServices.RequiresUnsafe").WithLocation(7, 41),
        };
 
        CreateCompilation([lib, RequiresUnsafeAttributeDefinition], parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics);
        CreateCompilation([lib, RequiresUnsafeAttributeDefinition], parseOptions: TestOptions.RegularPreview).VerifyEmitDiagnostics(expectedDiagnostics);
    }
 
    [Fact]
    public void Member_Event()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public event System.Action E1 { add { } remove { } }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public event System.Action E2 { add { } remove { } }
                }
                """,
            caller: """
                var c = new C();
                c.E1 += null;
                c.E2 += null;
                unsafe { c.E2 += null; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.E2", "C.add_E2", "C.remove_E2"],
            expectedSafeSymbols: ["C.E1", "C.add_E1", "C.remove_E1"],
            expectedDiagnostics:
            [
                // (3,6): error CS9362: 'C.E2.add' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.E2 += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "+=").WithArguments("C.E2.add").WithLocation(3, 6),
            ]);
 
        var source = """
            class C
            {
                event System.Action E1, E2;
                [System.Runtime.CompilerServices.RequiresUnsafe] event System.Action E3, E4;
                void M()
                {
                    E1();
                    E2();
                    E3();
                    E4();
 
                    E1 = null;
                    E2 = null;
                    E3 = null;
                    E4 = null;
 
                    unsafe { E3(); }
                    unsafe { E4(); }
                    unsafe { E3 = null; }
                    unsafe { E4 = null; }
                }
            }
            """;
        CreateCompilation([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (9,9): error CS9362: 'C.E3' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            //         E3();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "E3").WithArguments("C.E3").WithLocation(9, 9),
            // (10,9): error CS9362: 'C.E4' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            //         E4();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "E4").WithArguments("C.E4").WithLocation(10, 9),
            // (14,9): error CS9362: 'C.E3' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            //         E3 = null;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "E3").WithArguments("C.E3").WithLocation(14, 9),
            // (15,9): error CS9362: 'C.E4' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            //         E4 = null;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "E4").WithArguments("C.E4").WithLocation(15, 9));
    }
 
    [Fact]
    public void Member_Event_Accessors()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public event System.Action E1 { [System.Runtime.CompilerServices.RequiresUnsafe] add { } remove { } }
                    public event System.Action E2 { add { } [System.Runtime.CompilerServices.RequiresUnsafe] remove { } }
                }
                """,
            caller: """
                var c = new C();
                c.E1 += null; c.E1 -= null;
                c.E2 += null; c.E2 -= null;
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.add_E1", "C.remove_E2"],
            expectedSafeSymbols: ["C.E1", "C.remove_E1", "C.E2", "C.add_E2"],
            expectedDiagnostics:
            [
                // (2,6): error CS9362: 'C.E1.add' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.E1 += null; c.E1 -= null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "+=").WithArguments("C.E1.add").WithLocation(2, 6),
                // (3,20): error CS9362: 'C.E2.remove' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.E2 += null; c.E2 -= null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "-=").WithArguments("C.E2.remove").WithLocation(3, 20),
            ]);
    }
 
    [Fact]
    public void Member_Event_Override()
    {
        CompileAndVerifyUnsafe(
            lib: """
                #pragma warning disable CS0067 // unused event
                public class B
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public virtual event System.Action E1;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public virtual event System.Action E2 { add { } remove { } }
                    public virtual event System.Action E3;
                    public virtual event System.Action E4 { add { } remove { } }
                }
                """,
            caller: """
                var c = new C1();
                c.E1 += null;
                c.E2 += null;
                c.E3 += null;
                c.E4 += null;
 
                #pragma warning disable CS0067 // unused event
 
                class C1 : B
                {
                    public override event System.Action E1;
                    public override event System.Action E2 { add { } remove { } }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override event System.Action E3;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override event System.Action E4 { add { } remove { } }
                }
 
                class C2 : B
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override event System.Action E1;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public override event System.Action E2 { add { } remove { } }
                    public override event System.Action E3;
                    public override event System.Action E4 { add { } remove { } }
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["B.E1", "B.add_E1", "B.remove_E1", "B.E2", "B.add_E2", "B.remove_E2"],
            expectedSafeSymbols: ["B.E3", "B.add_E3", "B.remove_E3", "B.E4", "B.add_E4", "B.remove_E4"],
            expectedDiagnostics:
            [
                // (4,6): error CS9362: 'C1.E3.add' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.E3 += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "+=").WithArguments("C1.E3.add").WithLocation(4, 6),
                // (5,6): error CS9362: 'C1.E4.add' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.E4 += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "+=").WithArguments("C1.E4.add").WithLocation(5, 6),
                // (14,41): error CS9364: Unsafe member 'C1.E3' cannot override safe member 'B.E3'
                //     public override event System.Action E3;
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "E3").WithArguments("C1.E3", "B.E3").WithLocation(14, 41),
                // (16,41): error CS9364: Unsafe member 'C1.E4' cannot override safe member 'B.E4'
                //     public override event System.Action E4 { add { } remove { } }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "E4").WithArguments("C1.E4", "B.E4").WithLocation(16, 41),
            ],
            expectedDiagnosticsWhenReferencingLegacyLib:
            [
                // (4,6): error CS9362: 'C1.E3.add' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.E3 += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "+=").WithArguments("C1.E3.add").WithLocation(4, 6),
                // (5,6): error CS9362: 'C1.E4.add' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.E4 += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "+=").WithArguments("C1.E4.add").WithLocation(5, 6),
                // (14,41): error CS9364: Unsafe member 'C1.E3' cannot override safe member 'B.E3'
                //     public override event System.Action E3;
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "E3").WithArguments("C1.E3", "B.E3").WithLocation(14, 41),
                // (16,41): error CS9364: Unsafe member 'C1.E4' cannot override safe member 'B.E4'
                //     public override event System.Action E4 { add { } remove { } }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "E4").WithArguments("C1.E4", "B.E4").WithLocation(16, 41),
                // (22,41): error CS9364: Unsafe member 'C2.E1' cannot override safe member 'B.E1'
                //     public override event System.Action E1;
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "E1").WithArguments("C2.E1", "B.E1").WithLocation(22, 41),
                // (24,41): error CS9364: Unsafe member 'C2.E2' cannot override safe member 'B.E2'
                //     public override event System.Action E2 { add { } remove { } }
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "E2").WithArguments("C2.E2", "B.E2").WithLocation(24, 41),
            ]);
    }
 
    [Fact]
    public void Member_Event_Implementation()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public interface I
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    event System.Action E1;
                    event System.Action E2;
                }
                """,
            caller: """
                I i = new C1();
                i.E1 += null;
                i.E2 += null;
 
                #pragma warning disable CS0067 // unused event
 
                class C1 : I
                {
                    public event System.Action E1;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public event System.Action E2;
                }
 
                class C2 : I
                {
                    public event System.Action E1 { add { } remove { } }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public event System.Action E2 { add { } remove { } }
                }
 
                class C3 : I
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public event System.Action E1;
                    public event System.Action E2;
                }
 
                class C4 : I
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public event System.Action E1 { add { } remove { } }
                    public event System.Action E2 { add { } remove { } }
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["I.E1", "I.add_E1", "I.remove_E1"],
            expectedSafeSymbols: ["I.E2", "I.add_E2", "I.remove_E2"],
            expectedDiagnostics:
            [
                // (2,6): error CS9362: 'I.E1.add' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // i.E1 += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "+=").WithArguments("I.E1.add").WithLocation(2, 6),
                // (11,32): error CS9365: Unsafe member 'C1.E2' cannot implicitly implement safe member 'I.E2'
                //     public event System.Action E2;
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "E2").WithArguments("C1.E2", "I.E2").WithLocation(11, 32),
                // (18,32): error CS9365: Unsafe member 'C2.E2' cannot implicitly implement safe member 'I.E2'
                //     public event System.Action E2 { add { } remove { } }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "E2").WithArguments("C2.E2", "I.E2").WithLocation(18, 32),
            ],
            expectedDiagnosticsWhenReferencingLegacyLib:
            [
                // (11,32): error CS9365: Unsafe member 'C1.E2' cannot implicitly implement safe member 'I.E2'
                //     public event System.Action E2;
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "E2").WithArguments("C1.E2", "I.E2").WithLocation(11, 32),
                // (18,32): error CS9365: Unsafe member 'C2.E2' cannot implicitly implement safe member 'I.E2'
                //     public event System.Action E2 { add { } remove { } }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "E2").WithArguments("C2.E2", "I.E2").WithLocation(18, 32),
                // (24,32): error CS9365: Unsafe member 'C3.E1' cannot implicitly implement safe member 'I.E1'
                //     public event System.Action E1;
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "E1").WithArguments("C3.E1", "I.E1").WithLocation(24, 32),
                // (31,32): error CS9365: Unsafe member 'C4.E1' cannot implicitly implement safe member 'I.E1'
                //     public event System.Action E1 { add { } remove { } }
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "E1").WithArguments("C4.E1", "I.E1").WithLocation(31, 32),
            ]);
    }
 
    [Fact]
    public void Member_Constructor()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public C(int i) { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public C() { }
                }
                public unsafe class C2(int x)
                {
                    int _x = x;
                }
                [method: System.Runtime.CompilerServices.RequiresUnsafe] public class C3();
                """,
            caller: """
                _ = new C(0);
                _ = new C();
                unsafe { _ = new C(); }
                _ = new C2(0);
                _ = new C3();
                unsafe { _ = new C3(); }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: [Overload("C..ctor", parameterCount: 0)],
            expectedSafeSymbols: ["C", Overload("C..ctor", parameterCount: 1), "C2", "C2..ctor"],
            expectedDiagnostics:
            [
                // (2,5): error CS9362: 'C.C()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = new C();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C()").WithArguments("C.C()").WithLocation(2, 5),
                // (5,5): error CS9362: 'C3.C3()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = new C3();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C3()").WithArguments("C3.C3()").WithLocation(5, 5),
            ]);
    }
 
    [Fact]
    public void Member_Constructor_Base()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class B
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public B() { }
                }
                """,
            caller: """
                _ = new C1();
                _ = new C2();
                _ = new C3();
                _ = new C4();
                _ = new C5();
                _ = new D1();
                _ = new D2();
                unsafe { _ = new C5(); }
 
                class C1 : B;
                class C2 : B
                {
                    public C2() { }
                    public C2(int x) : base() { }
                }
                class D1() : B();
 
                unsafe class C3 : B;
                unsafe class C4 : B
                {
                    public C4() { }
                    public C4(int x) : base() { }
                }
                unsafe class D2() : B();
 
                class C5 : B
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public C5() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public C5(int x) : base() { }
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["B..ctor"],
            expectedSafeSymbols: ["B"],
            expectedDiagnostics:
            [
                // (5,5): error CS9362: 'C5.C5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = new C5();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C5()").WithArguments("C5.C5()").WithLocation(5, 5),
                // (10,1): error CS9362: 'B.B()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // class C1 : B;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "class C1 : B;").WithArguments("B.B()").WithLocation(10, 1),
                // (13,5): error CS9362: 'B.B()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public C2() { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "public C2() { }").WithArguments("B.B()").WithLocation(13, 5),
                // (14,22): error CS9362: 'B.B()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public C2(int x) : base() { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, ": base()").WithArguments("B.B()").WithLocation(14, 22),
                // (16,14): error CS9362: 'B.B()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // class D1() : B();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "B()").WithArguments("B.B()").WithLocation(16, 14),
                // (28,5): error CS9362: 'B.B()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     [System.Runtime.CompilerServices.RequiresUnsafe]
                //     public C5() { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, @"[System.Runtime.CompilerServices.RequiresUnsafe]
    public C5() { }").WithArguments("B.B()").WithLocation(28, 5),
                // (31,22): error CS9362: 'B.B()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public C5(int x) : base() { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, ": base()").WithArguments("B.B()").WithLocation(31, 22),
            ],
            expectedDiagnosticsWhenReferencingLegacyLib:
            [
                // (5,5): error CS9362: 'C5.C5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = new C5();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C5()").WithArguments("C5.C5()").WithLocation(5, 5),
            ]);
    }
 
    [Fact]
    public void Member_Constructor_This()
    {
        var source = """
            class C
            {
                public C() { }
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public C(int x) { }
                public C(string s) : this() { }
                public C(C c) : this(0) { }
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public C(int[] a) : this(0) { }
            }
            """;
        CreateCompilation([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (7,19): error CS9362: 'C.C(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            //     public C(C c) : this(0) { }
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, ": this(0)").WithArguments("C.C(int)").WithLocation(7, 19),
            // (9,23): error CS9362: 'C.C(int)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            //     public C(int[] a) : this(0) { }
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, ": this(0)").WithArguments("C.C(int)").WithLocation(9, 23));
    }
 
    [Fact]
    public void Member_Constructor_Static()
    {
        CreateCompilation(
            [
                """
                public class C
                {
                    public static readonly int F = 42;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    static C() { }
                }
                """,
                RequiresUnsafeAttributeDefinition,
            ],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (4,6): error CS9367: RequiresUnsafeAttribute cannot be applied to this symbol.
            //     [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.ERR_RequiresUnsafeAttributeUnsupportedMemberTarget, "System.Runtime.CompilerServices.RequiresUnsafe").WithLocation(4, 6));
    }
 
    [Fact]
    public void Member_Constructor_Attribute()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class A : System.Attribute
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public A() { }
                    public A(int x) { }
                }
                """,
            caller: """
                #pragma warning disable CS8321 // unused local function
                [A] void M1() { }
                [A(0)] void M2() { }
                unsafe { [A] void M3() { } }
                [A] unsafe void M4() { }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: [Overload("A..ctor", parameterCount: 0)],
            expectedSafeSymbols: ["A", Overload("A..ctor", parameterCount: 1)],
            expectedDiagnostics:
            [
                // (2,2): error CS9362: 'A.A()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // [A] void M1() { }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "A").WithArguments("A.A()").WithLocation(2, 2),
            ]);
    }
 
    [Fact]
    public void Member_Destructor()
    {
        var comp = CreateCompilation(
            [
                """
                class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    ~C() { }
                    void M() { Finalize(); }
                }
                class D : C
                {
                    ~D() { } // implicitly calls base finalizer
                }
                """,
                RequiresUnsafeAttributeDefinition,
            ],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,6): error CS9367: RequiresUnsafeAttribute cannot be applied to this symbol.
            //     [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.ERR_RequiresUnsafeAttributeUnsupportedMemberTarget, "System.Runtime.CompilerServices.RequiresUnsafe").WithLocation(3, 6),
            // (5,16): error CS0245: Destructors and object.Finalize cannot be called directly. Consider calling IDisposable.Dispose if available.
            //     void M() { Finalize(); }
            Diagnostic(ErrorCode.ERR_CallingFinalizeDeprecated, "Finalize()").WithLocation(5, 16));
 
        VerifyRequiresUnsafeAttribute(
            comp.SourceModule,
            expectedUnsafeSymbols: [],
            expectedSafeSymbols: ["C.Finalize"],
            expectedAttribute: ["C.Finalize"]);
    }
 
    [Fact]
    public void Member_Operator_Static()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public static C operator +(C c1, C c2) => c1;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public static C operator -(C c1, C c2) => c1;
                }
                """,
            caller: """
                var c = new C();
                _ = c + c;
                _ = c - c;
                unsafe { _ = c - c; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.op_Subtraction"],
            expectedSafeSymbols: ["C.op_Addition"],
            expectedDiagnostics:
            [
                // (3,5): error CS9362: 'C.operator -(C, C)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = c - c;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c - c").WithArguments("C.operator -(C, C)").WithLocation(3, 5),
            ]);
    }
 
    [Fact]
    public void Member_Operator_Static_Extension()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C;
                public static class E
                {
                    extension(C)
                    {
                        public static C operator +(C c1, C c2) => c1;
                        [System.Runtime.CompilerServices.RequiresUnsafe]
                        public static C operator -(C c1, C c2) => c1;
                    }
                }
                """,
            caller: """
                var c = new C();
                _ = c + c;
                _ = c - c;
                E.op_Addition(c, c);
                E.op_Subtraction(c, c);
                unsafe { _ = c - c; }
                unsafe { E.op_Subtraction(c, c); }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["E.op_Subtraction", ExtensionMember("E", "op_Subtraction")],
            expectedSafeSymbols: ["E.op_Addition", ExtensionMember("E", "op_Addition")],
            expectedDiagnostics:
            [
                // (3,5): error CS9362: 'E.extension(C).operator -(C, C)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = c - c;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c - c").WithArguments("E.extension(C).operator -(C, C)").WithLocation(3, 5),
                // (5,1): error CS9362: 'E.op_Subtraction(C, C)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // E.op_Subtraction(c, c);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "E.op_Subtraction(c, c)").WithArguments("E.op_Subtraction(C, C)").WithLocation(5, 1),
            ]);
    }
 
    [Fact]
    public void Member_Operator_Instance()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public void operator +=(C c) { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void operator -=(C c) { }
                }
                """,
            caller: """
                var c = new C();
                c += c;
                c -= c;
                unsafe { c -= c; }
                """,
            additionalSources: [CompilerFeatureRequiredAttribute, RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.op_SubtractionAssignment"],
            expectedSafeSymbols: ["C.op_AdditionAssignment"],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'C.operator -=(C)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c -= c;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c -= c").WithArguments("C.operator -=(C)").WithLocation(3, 1),
            ]);
    }
 
    [Fact]
    public void Member_Operator_Instance_Extension()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C;
                public static class E
                {
                    extension(C c1)
                    {
                        public void operator +=(C c2) { }
                        [System.Runtime.CompilerServices.RequiresUnsafe]
                        public void operator -=(C c2) { }
                    }
                }
                """,
            caller: """
                var c = new C();
                c += c;
                c -= c;
                E.op_AdditionAssignment(c, c);
                E.op_SubtractionAssignment(c, c);
                unsafe { c -= c; }
                unsafe { E.op_SubtractionAssignment(c, c); }
                """,
            additionalSources: [CompilerFeatureRequiredAttribute, RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["E.op_SubtractionAssignment", ExtensionMember("E", "op_SubtractionAssignment")],
            expectedSafeSymbols: ["E.op_AdditionAssignment", ExtensionMember("E", "op_AdditionAssignment")],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'E.extension(C).operator -=(C)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c -= c;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c -= c").WithArguments("E.extension(C).operator -=(C)").WithLocation(3, 1),
                // (5,1): error CS9362: 'E.op_SubtractionAssignment(C, C)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // E.op_SubtractionAssignment(c, c);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "E.op_SubtractionAssignment(c, c)").WithArguments("E.op_SubtractionAssignment(C, C)").WithLocation(5, 1),
            ]);
    }
 
    [Fact]
    public void Member_Operator_Instance_Unary()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public void operator ++() { }
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public void operator --() { }
                }
                """,
            caller: """
                var c = new C();
                c++;
                c--;
                unsafe { c--; }
                """,
            additionalSources: [CompilerFeatureRequiredAttribute, RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: ["C.op_DecrementAssignment"],
            expectedSafeSymbols: ["C.op_IncrementAssignment"],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'C.operator --()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c--;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c--").WithArguments("C.operator --()").WithLocation(3, 1),
            ]);
    }
 
    [Fact]
    public void Member_Operator_Conversion()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    public static implicit operator int(C c) => 0;
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public static implicit operator string(C c) => "";
                }
                """,
            caller: """
                var c = new C();
                int i = c;
                string s = c;
                unsafe { string s2 = c; }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            expectedUnsafeSymbols: [OverloadByReturnType("C.op_Implicit", "System.String")],
            expectedSafeSymbols: [OverloadByReturnType("C.op_Implicit", "System.Int32")],
            expectedDiagnostics:
            [
                // (3,12): error CS9362: 'C.implicit operator string(C)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // string s = c;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c").WithArguments("C.implicit operator string(C)").WithLocation(3, 12),
            ]);
    }
 
    [Theory, CombinatorialData]
    public void Member_FunctionPointer(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            public unsafe class C
            {
                public delegate*<string> F;
            }
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            var c = new C();
            string s = c.F();
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,12): error CS9360: This operation may only be used in an unsafe context
            // string s = c.F();
            Diagnostic(ErrorCode.ERR_UnsafeOperation, "c.F()").WithLocation(2, 12));
 
        CompileAndVerify("""
            var c = new C();
            unsafe { string s = c.F(); }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: [],
                expectedSafeSymbols: ["C", "C.F", (object)getFunctionPointerType, (object)getFunctionPointerMethod],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (2,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // string s = c.F();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "c.F()").WithLocation(2, 12));
 
        static Symbol getFunctionPointerType(ModuleSymbol module)
        {
            return module.GlobalNamespace.GetMember("C.F").GetTypeOrReturnType().Type;
        }
 
        static Symbol getFunctionPointerMethod(ModuleSymbol module)
        {
            var functionPointerType = (FunctionPointerTypeSymbol)getFunctionPointerType(module);
            return functionPointerType.Signature;
        }
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Method_ParameterType(
        [CombinatorialValues("int*", "int*[]", "delegate*<void>")] string parameterType,
        bool unsafeOnType,
        bool useCompilationReference)
    {
        var (typeModifier, methodModifier) = unsafeOnType ? ("unsafe", "") : ("", "unsafe");
 
        var lib = CreateCompilation($$"""
            public {{typeModifier}} class C
            {
                public {{methodModifier}} void M1(int x) { }
                public {{methodModifier}} void M2({{parameterType}} y) { }
            }
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            var c = new C();
            c.M1(0);
            c.M2(null);
            unsafe { c.M2(null); }
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,1): error CS9363: 'C.M2(int*)' must be used in an unsafe context because it has pointers in its signature
            // c.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c.M2(null)").WithArguments($"C.M2({parameterType})").WithLocation(3, 1));
 
        CompileAndVerify("""
            var c = new C();
            c.M1(0);
            unsafe { c.M2(null); }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: ["C.M2"],
                expectedSafeSymbols: ["C", "C.M1"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (3,6): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // c.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "null").WithLocation(3, 6),
            // (3,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // c.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "c.M2(null)").WithLocation(3, 1));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Method_ReturnType(
        [CombinatorialValues("int*", "int*[]", "delegate*<void>")] string returnType,
        bool useCompilationReference)
    {
        var lib = CreateCompilation($$"""
            public class C
            {
                public unsafe int M1(int i) => i;
                public unsafe {{returnType}} M2(string s) => null;
            }
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            var c = new C();
            c.M1(0);
            c.M2(null);
            unsafe { c.M2(null); }
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,1): error CS9363: 'C.M2(string)' must be used in an unsafe context because it has pointers in its signature
            // c.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c.M2(null)").WithArguments("C.M2(string)").WithLocation(3, 1));
 
        CompileAndVerify("""
            var c = new C();
            c.M1(0);
            unsafe { c.M2(null); }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: ["C.M2"],
                expectedSafeSymbols: ["C", "C.M1"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (3,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // c.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "c.M2(null)").WithLocation(3, 1));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Method_ConstraintType(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            public class C
            {
                public unsafe void M<T>(T t) where T : I<int*[]> { }
            }
            public interface I<T>;
            public unsafe class D : I<int*[]>;
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            var c = new C();
            c.M<D>(null);
            """;
 
        CompileAndVerify(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            symbolValidator: validate)
            .VerifyDiagnostics();
 
        CompileAndVerify(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe,
            symbolValidator: validate)
            .VerifyDiagnostics();
 
        static void validate(ModuleSymbol module)
        {
            VerifyRequiresUnsafeAttribute(
                module.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: [],
                expectedSafeSymbols: ["C", "I", "C.M", "D"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit);
        }
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Method_DefaultParameterValue(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            public class C
            {
                public unsafe void M(string s = nameof(I<int*[]>)) { }
            }
            public interface I<T>;
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            var c = new C();
            c.M(s: null);
            """;
 
        CompileAndVerify(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            symbolValidator: validate)
            .VerifyDiagnostics();
 
        CompileAndVerify(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe,
            symbolValidator: validate)
            .VerifyDiagnostics();
 
        static void validate(ModuleSymbol module)
        {
            VerifyRequiresUnsafeAttribute(
                module.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: [],
                expectedSafeSymbols: ["C", "C.M", "I"]);
        }
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Method_ExtensionMethod_ReceiverType(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            public static class E
            {
                public static unsafe void M1(this int x) { }
                public static unsafe void M2(this int*[] y) { }
            }
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            123.M1();
            new int*[0].M2();
            E.M1(123);
            E.M2(null);
            unsafe { new int*[0].M2(); }
            unsafe { E.M2(null); }
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,1): error CS9363: 'E.M2(int*[])' must be used in an unsafe context because it has pointers in its signature
            // new int*[0].M2();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "new int*[0].M2()").WithArguments("E.M2(int*[])").WithLocation(2, 1),
            // (4,1): error CS9363: 'E.M2(int*[])' must be used in an unsafe context because it has pointers in its signature
            // E.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "E.M2(null)").WithArguments("E.M2(int*[])").WithLocation(4, 1));
 
        CompileAndVerify("""
            123.M1();
            E.M1(123);
            unsafe { new int*[0].M2(); }
            unsafe { E.M2(null); }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: ["E.M2"],
                expectedSafeSymbols: ["E", "E.M1"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (2,5): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // new int*[0].M2();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(2, 5),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // new int*[0].M2();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "new int*[0]").WithLocation(2, 1),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // new int*[0].M2();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "new int*[0].M2()").WithLocation(2, 1),
            // (4,6): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // E.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "null").WithLocation(4, 6),
            // (4,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // E.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "E.M2(null)").WithLocation(4, 1));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Method_ExtensionMember_ReceiverType(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            public unsafe static class E
            {
                extension(int x)
                {
                    public void M1() { }
                }
 
                extension(int*[] y)
                {
                    public void M2() { }
                }
            }
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            123.M1();
            new int*[0].M2();
            E.M1(123);
            E.M2(null);
            unsafe { new int*[0].M2(); }
            unsafe { E.M2(null); }
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,1): error CS9363: 'E.extension(int*[]).M2()' must be used in an unsafe context because it has pointers in its signature
            // new int*[0].M2();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "new int*[0].M2()").WithArguments("E.extension(int*[]).M2()").WithLocation(2, 1),
            // (4,1): error CS9363: 'E.M2(int*[])' must be used in an unsafe context because it has pointers in its signature
            // E.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "E.M2(null)").WithArguments("E.M2(int*[])").WithLocation(4, 1));
 
        CompileAndVerify("""
            123.M1();
            E.M1(123);
            unsafe { new int*[0].M2(); }
            unsafe { E.M2(null); }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: ["E.M2", ExtensionMember("E", "M2")],
                expectedSafeSymbols: ["E", "E.M1", ExtensionMember("E", "M1")],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (2,5): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // new int*[0].M2();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(2, 5),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // new int*[0].M2();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "new int*[0]").WithLocation(2, 1),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // new int*[0].M2();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "new int*[0].M2()").WithLocation(2, 1),
            // (4,6): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // E.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "null").WithLocation(4, 6),
            // (4,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // E.M2(null);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "E.M2(null)").WithLocation(4, 1));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Method_Override(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            public class B
            {
                public unsafe virtual int* M1() => null;
                public unsafe virtual int* M2() => null;
                public unsafe virtual int* M3() => null;
                public unsafe virtual void M4() { }
                public unsafe virtual void M5() { }
                public unsafe virtual void M6() { }
            }
 
            public class C : B
            {
                public unsafe override int* M1() => null;
                public unsafe new virtual int* M2() => null;
                public unsafe override void M4() { }
                public unsafe new virtual void M5() { }
            }
            """,
            options: TestOptions.UnsafeReleaseDll)
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        CreateCompilation("""
            var d1 = new D1(); d1.M1(); d1.M2(); d1.M3(); d1.M4(); d1.M5(); d1.M6();
            var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
            var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
            C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
 
            class D1 : C
            {
                public override int* M1() => null;
                public override int* M2() => null;
                public override int* M3() => null;
                public override void M4() { }
                public override void M5() { }
                public override void M6() { }
                public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
            }
 
            class D2 : C
            {
                public unsafe override int* M1() => null;
                public unsafe override int* M2() => null;
                public unsafe override int* M3() => null;
                public unsafe override void M4() { }
                public unsafe override void M5() { }
                public unsafe override void M6() { }
            }
 
            class D3 : C;
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,20): error CS9363: 'C.M1()' must be used in an unsafe context because it has pointers in its signature
            // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "d3.M1()").WithArguments("C.M1()").WithLocation(3, 20),
            // (3,29): error CS9363: 'C.M2()' must be used in an unsafe context because it has pointers in its signature
            // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "d3.M2()").WithArguments("C.M2()").WithLocation(3, 29),
            // (3,38): error CS9363: 'B.M3()' must be used in an unsafe context because it has pointers in its signature
            // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "d3.M3()").WithArguments("B.M3()").WithLocation(3, 38),
            // (4,11): error CS9363: 'C.M1()' must be used in an unsafe context because it has pointers in its signature
            // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c.M1()").WithArguments("C.M1()").WithLocation(4, 11),
            // (4,19): error CS9363: 'C.M2()' must be used in an unsafe context because it has pointers in its signature
            // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c.M2()").WithArguments("C.M2()").WithLocation(4, 19),
            // (4,27): error CS9363: 'B.M3()' must be used in an unsafe context because it has pointers in its signature
            // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c.M3()").WithArguments("B.M3()").WithLocation(4, 27),
            // (14,31): error CS9363: 'C.M1()' must be used in an unsafe context because it has pointers in its signature
            //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "base.M1()").WithArguments("C.M1()").WithLocation(14, 31),
            // (14,42): error CS9363: 'C.M2()' must be used in an unsafe context because it has pointers in its signature
            //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "base.M2()").WithArguments("C.M2()").WithLocation(14, 42),
            // (14,53): error CS9363: 'B.M3()' must be used in an unsafe context because it has pointers in its signature
            //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "base.M3()").WithArguments("B.M3()").WithLocation(14, 53));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Method_Implementation(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            public interface I
            {
                unsafe int* M1();
                unsafe void M2();
            }
            """,
            options: TestOptions.UnsafeReleaseDll)
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            I i = new C1();
            i.M1();
            i.M2();
 
            public class C1 : I
            {
                public int* M1() => null;
                public void M2() { }
            }
 
            public class C2 : I
            {
                int* I.M1() => null;
                void I.M2() { }
            }
 
            public class C3 : I
            {
                public unsafe int* M1() => null;
                public unsafe void M2() { }
            }
 
            public class C4 : I
            {
                unsafe int* I.M1() => null;
                unsafe void I.M2() { }
            }
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,1): error CS9363: 'I.M1()' must be used in an unsafe context because it has pointers in its signature
            // i.M1();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "i.M1()").WithArguments("I.M1()").WithLocation(2, 1));
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // i.M1();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "i.M1()").WithLocation(2, 1),
            // (7,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     public int* M1() => null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(7, 12),
            // (13,5): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     int* I.M1() => null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(13, 5));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Method_Implementation_Generic(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            public interface I<T>
            {
                T M1();
                void M2();
            }
            """,
            options: TestOptions.UnsafeReleaseDll)
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            I<int*[]> i = new C1();
            i.M1();
            i.M2();
 
            public class C1 : I<int*[]>
            {
                public int*[] M1() => null;
                public void M2() { }
            }
 
            public class C2 : I<int*[]>
            {
                int*[] I<int*[]>.M1() => null;
                void I<int*[]>.M2() { }
            }
 
            public class C3 : I<int*[]>
            {
                public unsafe int*[] M1() => null;
                public unsafe void M2() { }
            }
 
            public class C4 : I<int*[]>
            {
                unsafe int*[] I<int*[]>.M1() => null;
                unsafe void I<int*[]>.M2() { }
            }
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (5,21): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // public class C1 : I<int*[]>
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(5, 21),
            // (11,21): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // public class C2 : I<int*[]>
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(11, 21),
            // (23,21): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // public class C4 : I<int*[]>
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(23, 21),
            // (17,21): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // public class C3 : I<int*[]>
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(17, 21),
            // (7,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     public int*[] M1() => null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(7, 12),
            // (13,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     int*[] I<int*[]>.M1() => null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(13, 14),
            // (14,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     void I<int*[]>.M2() { }
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(14, 12),
            // (13,5): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     int*[] I<int*[]>.M1() => null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(13, 5),
            // (1,3): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // I<int*[]> i = new C1();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 3),
            // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // i.M1();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "i.M1()").WithLocation(2, 1));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Property(
        [CombinatorialValues("int*", "int*[]", "delegate*<void>")] string type,
        bool useCompilationReference)
    {
        var lib = CreateCompilation($$"""
            public class C
            {
                public unsafe int P1 { get; set; }
                public unsafe {{type}} P2 { get; set; }
            }
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            var c = new C();
            c.P1 = c.P1;
            c.P2 = c.P2;
            unsafe { c.P2 = c.P2; }
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,1): error CS9363: 'C.P2.set' must be used in an unsafe context because it has pointers in its signature
            // c.P2 = c.P2;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c.P2").WithArguments("C.P2.set").WithLocation(3, 1),
            // (3,8): error CS9363: 'C.P2.get' must be used in an unsafe context because it has pointers in its signature
            // c.P2 = c.P2;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c.P2").WithArguments("C.P2.get").WithLocation(3, 8));
 
        CompileAndVerify("""
            var c = new C();
            c.P1 = c.P1;
            unsafe { c.P2 = c.P2; }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: ["C.P2", "C.get_P2", "C.set_P2"],
                expectedSafeSymbols: ["C", "C.P1", "C.get_P1", "C.set_P1"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (3,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // c.P2 = c.P2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "c.P2").WithLocation(3, 1),
            // (3,8): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // c.P2 = c.P2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "c.P2").WithLocation(3, 8),
            // (3,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // c.P2 = c.P2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "c.P2 = c.P2").WithLocation(3, 1));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Property_Extension_ReceiverType(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            public unsafe static class E
            {
                extension(int x)
                {
                    public int P1 { get => 0; set { } }
                }
 
                extension(int*[] y)
                {
                    public int P2 { get => 0; set { } }
                }
            }
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            var x = 123;
            x.P1 = x.P1;
            new int*[0].P2 = new int*[0].P2;
            E.get_P1(x); E.set_P1(x, 0);
            E.get_P2(null); E.set_P2(null, 0);
            unsafe { new int*[0].P2 = new int*[0].P2; }
            unsafe { E.get_P2(null); E.set_P2(null, 0); }
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,1): error CS9363: 'E.extension(int*[]).P2.set' must be used in an unsafe context because it has pointers in its signature
            // new int*[0].P2 = new int*[0].P2;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "new int*[0].P2").WithArguments("E.extension(int*[]).P2.set").WithLocation(3, 1),
            // (3,18): error CS9363: 'E.extension(int*[]).P2.get' must be used in an unsafe context because it has pointers in its signature
            // new int*[0].P2 = new int*[0].P2;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "new int*[0].P2").WithArguments("E.extension(int*[]).P2.get").WithLocation(3, 18),
            // (5,1): error CS9363: 'E.get_P2(int*[])' must be used in an unsafe context because it has pointers in its signature
            // E.get_P2(null); E.set_P2(null, 0);
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "E.get_P2(null)").WithArguments("E.get_P2(int*[])").WithLocation(5, 1),
            // (5,17): error CS9363: 'E.set_P2(int*[], int)' must be used in an unsafe context because it has pointers in its signature
            // E.get_P2(null); E.set_P2(null, 0);
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "E.set_P2(null, 0)").WithArguments("E.set_P2(int*[], int)").WithLocation(5, 17));
 
        CompileAndVerify("""
            var x = 123;
            x.P1 = x.P1;
            E.get_P1(x); E.set_P1(x, 0);
            unsafe { new int*[0].P2 = new int*[0].P2; }
            unsafe { E.get_P2(null); E.set_P2(null, 0); }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: [ExtensionMember("E", "P2"), "E.get_P2", ExtensionMember("E", "get_P2"), "E.set_P2", ExtensionMember("E", "set_P2")],
                expectedSafeSymbols: ["E", ExtensionMember("E", "P1"), "E.get_P1", ExtensionMember("E", "get_P1"), "E.set_P1", ExtensionMember("E", "set_P1")],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (3,5): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // new int*[0].P2 = new int*[0].P2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 5),
            // (3,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // new int*[0].P2 = new int*[0].P2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "new int*[0]").WithLocation(3, 1),
            // (3,22): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // new int*[0].P2 = new int*[0].P2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 22),
            // (3,18): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // new int*[0].P2 = new int*[0].P2;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "new int*[0]").WithLocation(3, 18),
            // (5,10): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // E.get_P2(null); E.set_P2(null, 0);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "null").WithLocation(5, 10),
            // (5,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // E.get_P2(null); E.set_P2(null, 0);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "E.get_P2(null)").WithLocation(5, 1),
            // (5,26): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // E.get_P2(null); E.set_P2(null, 0);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "null").WithLocation(5, 26),
            // (5,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // E.get_P2(null); E.set_P2(null, 0);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "E.set_P2(null, 0)").WithLocation(5, 17));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Indexer(
        [CombinatorialValues("int*", "int*[]", "delegate*<void>")] string type,
        bool useCompilationReference)
    {
        var lib = CreateCompilation($$"""
            public class C1
            {
                public unsafe int this[int i] { get => i; set { } }
            }
            public class C2
            {
                public unsafe {{type}} this[int i] { get => null; set { } }
            }
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            var c1 = new C1();
            c1[0] = c1[0];
            var c2 = new C2();
            c2[0] = c2[0];
            unsafe { c2[0] = c2[0]; }
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (4,1): error CS9363: 'C2.this[int].set' must be used in an unsafe context because it has pointers in its signature
            // c2[0] = c2[0];
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c2[0]").WithArguments("C2.this[int].set").WithLocation(4, 1),
            // (4,9): error CS9363: 'C2.this[int].get' must be used in an unsafe context because it has pointers in its signature
            // c2[0] = c2[0];
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c2[0]").WithArguments("C2.this[int].get").WithLocation(4, 9));
 
        CompileAndVerify("""
            var c1 = new C1();
            c1[0] = c1[0];
            var c2 = new C2();
            unsafe { c2[0] = c2[0]; }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: ["C2.this[]", "C2.get_Item", "C2.set_Item"],
                expectedSafeSymbols: ["C1", "C2", "C1.this[]", "C1.get_Item", "C1.set_Item"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (4,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // c2[0] = c2[0];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "c2[0]").WithLocation(4, 1),
            // (4,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // c2[0] = c2[0];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "c2[0]").WithLocation(4, 9),
            // (4,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // c2[0] = c2[0];
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "c2[0] = c2[0]").WithLocation(4, 1));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Event(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            #pragma warning disable CS0067 // unused event
            public class C
            {
                public unsafe event System.Action E1;
                public unsafe event System.Action<int*[]> E2;
            }
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            var c = new C();
            c.E1 += null;
            c.E2 += null;
            unsafe { c.E2 += null; }
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,6): error CS9363: 'C.E2.add' must be used in an unsafe context because it has pointers in its signature
            // c.E2 += null;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "+=").WithArguments("C.E2.add").WithLocation(3, 6));
 
        CompileAndVerify("""
            var c = new C();
            c.E1 += null;
            unsafe { c.E2 += null; }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: ["C.E2", "C.add_E2", "C.remove_E2"],
                expectedSafeSymbols: ["C", "C.E1", "C.add_E1", "C.remove_E1"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (3,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // c.E2 += null;
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "c.E2").WithLocation(3, 1));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Constructor(bool useCompilationReference)
    {
        var lib = CreateCompilation("""
            public class C
            {
                public unsafe C() { }
                public unsafe C(int* p) { }
            }
            """,
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            _ = new C();
            _ = new C(null);
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (2,5): error CS9363: 'C.C(int*)' must be used in an unsafe context because it has pointers in its signature
            // _ = new C(null);
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "new C(null)").WithArguments("C.C(int*)").WithLocation(2, 5));
 
        CompileAndVerify("""
            _ = new C();
            unsafe { _ = new C(null); }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: [Overload("C..ctor", parameterCount: 1)],
                expectedSafeSymbols: ["C", Overload("C..ctor", parameterCount: 0)],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyDiagnostics(
            // (2,5): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // _ = new C(null);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "new C(null)").WithLocation(2, 5),
            // (2,11): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            // _ = new C(null);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "null").WithLocation(2, 11));
    }
 
    [Theory, CombinatorialData]
    public void CompatMode_Operator(bool useCompilationReference)
    {
        var lib = CreateCompilation(
            [
                """
                public class C
                {
                    public unsafe void operator +=(int i) { }
                    public unsafe void operator -=(int* p) { }
                }
                """,
                CompilerFeatureRequiredAttribute,
            ],
            options: TestOptions.UnsafeReleaseDll,
            assemblyName: "lib")
            .VerifyDiagnostics();
        var libRef = AsReference(lib, useCompilationReference);
 
        var source = """
            var c = new C();
            c += 0;
            c -= null;
            """;
 
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,1): error CS9363: 'C.operator -=(int*)' must be used in an unsafe context because it has pointers in its signature
            // c -= null;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c -= null").WithArguments("C.operator -=(int*)").WithLocation(3, 1));
 
        CompileAndVerify("""
            var c = new C();
            c += 0;
            unsafe { c -= null; }
            """,
            [libRef],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m.ReferencedAssemblySymbols.Single(a => a.Name == "lib").Modules.Single(),
                expectedUnsafeSymbols: ["C.op_SubtractionAssignment"],
                expectedSafeSymbols: ["C", "C.op_AdditionAssignment"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit))
            .VerifyDiagnostics();
 
        // https://github.com/dotnet/roslyn/issues/81967: operator invocations involving pointers are allowed outside unsafe context
        CreateCompilation(source,
            [libRef],
            options: TestOptions.UnsafeReleaseExe)
            .VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Extern_Method()
    {
        var libSource = """
            #pragma warning disable CS0626 // extern without attributes
            using System.Runtime.CompilerServices;
            using System.Runtime.InteropServices;
 
            public class C
            {
                public void M1() { }
                public extern void M2();
                [DllImport("test")] public static extern void M3();
                [MethodImpl(MethodImplOptions.InternalCall)] public extern void M4();
            }
            """;
 
        var callerSource = """
            var c = new C();
            c.M1();
            c.M2();
            C.M3();
            c.M4();
            """;
 
        object[] unsafeSymbols = ["C.M2", "C.M3", "C.M4"];
 
        var commonDiagnostics = new[]
        {
            // (3,1): error CS9362: 'C.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // c.M2();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M2()").WithArguments("C.M2()").WithLocation(3, 1),
            // (4,1): error CS9362: 'C.M3()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // C.M3();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "C.M3()").WithArguments("C.M3()").WithLocation(4, 1),
            // (5,1): error CS9362: 'C.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // c.M4();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M4()").WithArguments("C.M4()").WithLocation(5, 1),
        };
 
        CompileAndVerifyUnsafe(
            libSource,
            callerSource,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: unsafeSymbols,
            expectedSafeSymbols: ["C", "C.M1"],
            expectedNoAttributeInSource: unsafeSymbols,
            expectedNoAttributeUnderLegacyRules: unsafeSymbols,
            expectedDiagnostics: commonDiagnostics);
 
        CreateCompilation([libSource, callerSource],
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            [
                .. commonDiagnostics,
                // (8,24): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public extern void M2();
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "M2").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(8, 24),
                // (9,51): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     [DllImport("test")] public static extern void M3();
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "M3").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(9, 51),
                // (10,69): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     [MethodImpl(MethodImplOptions.InternalCall)] public extern void M4();
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "M4").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(10, 69),
            ]);
 
        CreateCompilation([libSource, RequiresUnsafeAttributeDefinition],
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (8,24): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public extern void M2();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "M2").WithArguments("updated memory safety rules").WithLocation(8, 24),
            // (9,51): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [DllImport("test")] public static extern void M3();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "M3").WithArguments("updated memory safety rules").WithLocation(9, 51),
            // (10,69): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     [MethodImpl(MethodImplOptions.InternalCall)] public extern void M4();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "M4").WithArguments("updated memory safety rules").WithLocation(10, 69));
 
        CreateCompilation(libSource,
            parseOptions: TestOptions.Regular14)
            .VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Extern_Method_WithPointers()
    {
        static string getLibSource(string modifiers) => $$"""
            #pragma warning disable CS0626 // extern without attributes
            public class C
            {
                public {{modifiers}} int* M();
            }
            """;
 
        var callerSource = """
            var c = new C();
            c.M();
            """;
 
        var libUpdated = CreateCompilation(
            [getLibSource("extern"), RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libUpdatedRef = AsReference(libUpdated, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libUpdatedRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (2,1): error CS9362: 'C.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.M();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M()").WithArguments("C.M()").WithLocation(2, 1))
                .GetReferencedAssemblySymbol(libUpdatedRef);
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: ["C.M"],
                expectedSafeSymbols: ["C"],
                expectedNoAttributeInSource: ["C.M"]);
        }
 
        CreateCompilation(getLibSource("extern")).VerifyDiagnostics(
            // (4,19): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     public extern int* M();
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(4, 19));
 
        // When compiling the lib under legacy rules, extern members are not unsafe, but members with pointers are.
        var libLegacy = CreateCompilation(
            getLibSource("unsafe extern"),
            options: TestOptions.UnsafeReleaseDll)
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libLegacyRef = AsReference(libLegacy, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libLegacyRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (2,1): error CS9363: 'C.M()' must be used in an unsafe context because it has pointers in its signature
                // c.M();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c.M()").WithArguments("C.M()").WithLocation(2, 1))
                .GetReferencedAssemblySymbol(libLegacyRef);
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: ["C.M"],
                expectedSafeSymbols: ["C"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit);
        }
    }
 
    [Fact]
    public void Extern_Method_Explicit()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public extern void M();
                }
                """,
            caller: """
                var c = new C();
                c.M();
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["C.M"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (2,1): error CS9362: 'C.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.M();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M()").WithArguments("C.M()").WithLocation(2, 1),
            ]);
    }
 
    [Fact]
    public void Extern_Method_Override()
    {
        object[] unsafeSymbols = ["B.M1", "B.M2", "B.M3"];
 
        CompileAndVerifyUnsafe(
            lib: """
                #pragma warning disable CS0626 // extern without attributes
                public class B
                {
                    public extern virtual void M1();
                    public extern virtual void M2();
                    public extern virtual void M3();
                    public virtual void M4() { }
                    public virtual void M5() { }
                    public virtual void M6() { }
                }
                """,
            caller: """
                #pragma warning disable CS0626 // extern without attributes
                var d1 = new D1(); d1.M1(); d1.M2(); d1.M3(); d1.M4(); d1.M5(); d1.M6();
                var d2 = new D2(); d2.M1(); d2.M2(); d2.M3(); d2.M4(); d2.M5(); d2.M6();
                var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                var d4 = new D4(); d4.M1(); d4.M2(); d4.M3(); d4.M4(); d4.M5(); d4.M6();
                C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
 
                class C : B
                {
                    public extern override void M1();
                    public extern new virtual void M2();
                    public extern override void M4();
                    public extern new virtual void M5();
                }
 
                class D1 : C
                {
                    public override void M1() { }
                    public override void M2() { }
                    public override void M3() { }
                    public override void M4() { }
                    public override void M5() { }
                    public override void M6() { }
                    public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
                }
 
                class D2 : C
                {
                    public unsafe override void M1() { }
                    public unsafe override void M2() { }
                    public unsafe override void M3() { }
                    public unsafe override void M4() { }
                    public unsafe override void M5() { }
                    public unsafe override void M6() { }
                }
 
                class D3 : C
                {
                    public extern override void M1();
                    public extern override void M2();
                    public extern override void M3();
                    public extern override void M4();
                    public extern override void M5();
                    public extern override void M6();
                }
 
                class D4 : C;
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: unsafeSymbols,
            expectedSafeSymbols: ["B", "B.M4", "B.M5", "B.M6"],
            expectedNoAttributeInSource: unsafeSymbols,
            expectedNoAttributeUnderLegacyRules: unsafeSymbols,
            expectedDiagnostics:
            [
                // (4,20): error CS9362: 'D3.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M1()").WithArguments("D3.M1()").WithLocation(4, 20),
                // (4,29): error CS9362: 'D3.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M2()").WithArguments("D3.M2()").WithLocation(4, 29),
                // (4,38): error CS9362: 'D3.M3()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M3()").WithArguments("D3.M3()").WithLocation(4, 38),
                // (4,47): error CS9362: 'D3.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M4()").WithArguments("D3.M4()").WithLocation(4, 47),
                // (4,56): error CS9362: 'D3.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M5()").WithArguments("D3.M5()").WithLocation(4, 56),
                // (4,65): error CS9362: 'D3.M6()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M6()").WithArguments("D3.M6()").WithLocation(4, 65),
                // (5,20): error CS9362: 'C.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d4 = new D4(); d4.M1(); d4.M2(); d4.M3(); d4.M4(); d4.M5(); d4.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d4.M1()").WithArguments("C.M1()").WithLocation(5, 20),
                // (5,29): error CS9362: 'C.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d4 = new D4(); d4.M1(); d4.M2(); d4.M3(); d4.M4(); d4.M5(); d4.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d4.M2()").WithArguments("C.M2()").WithLocation(5, 29),
                // (5,38): error CS9362: 'B.M3()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d4 = new D4(); d4.M1(); d4.M2(); d4.M3(); d4.M4(); d4.M5(); d4.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d4.M3()").WithArguments("B.M3()").WithLocation(5, 38),
                // (5,47): error CS9362: 'C.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d4 = new D4(); d4.M1(); d4.M2(); d4.M3(); d4.M4(); d4.M5(); d4.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d4.M4()").WithArguments("C.M4()").WithLocation(5, 47),
                // (5,56): error CS9362: 'C.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d4 = new D4(); d4.M1(); d4.M2(); d4.M3(); d4.M4(); d4.M5(); d4.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d4.M5()").WithArguments("C.M5()").WithLocation(5, 56),
                // (6,11): error CS9362: 'C.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M1()").WithArguments("C.M1()").WithLocation(6, 11),
                // (6,19): error CS9362: 'C.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M2()").WithArguments("C.M2()").WithLocation(6, 19),
                // (6,27): error CS9362: 'B.M3()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M3()").WithArguments("B.M3()").WithLocation(6, 27),
                // (6,35): error CS9362: 'C.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M4()").WithArguments("C.M4()").WithLocation(6, 35),
                // (6,43): error CS9362: 'C.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M5()").WithArguments("C.M5()").WithLocation(6, 43),
                // (12,33): error CS9364: Unsafe member 'C.M4()' cannot override safe member 'B.M4()'
                //     public extern override void M4();
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M4").WithArguments("C.M4()", "B.M4()").WithLocation(12, 33),
                // (24,31): error CS9362: 'C.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "base.M1()").WithArguments("C.M1()").WithLocation(24, 31),
                // (24,42): error CS9362: 'C.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "base.M2()").WithArguments("C.M2()").WithLocation(24, 42),
                // (24,53): error CS9362: 'B.M3()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "base.M3()").WithArguments("B.M3()").WithLocation(24, 53),
                // (24,64): error CS9362: 'C.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "base.M4()").WithArguments("C.M4()").WithLocation(24, 64),
                // (24,75): error CS9362: 'C.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "base.M5()").WithArguments("C.M5()").WithLocation(24, 75),
                // (42,33): error CS9364: Unsafe member 'D3.M4()' cannot override safe member 'B.M4()'
                //     public extern override void M4();
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M4").WithArguments("D3.M4()", "B.M4()").WithLocation(42, 33),
                // (44,33): error CS9364: Unsafe member 'D3.M6()' cannot override safe member 'B.M6()'
                //     public extern override void M6();
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M6").WithArguments("D3.M6()", "B.M6()").WithLocation(44, 33),
            ],
            expectedDiagnosticsWhenReferencingLegacyLib:
            [
                // (4,20): error CS9362: 'D3.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M1()").WithArguments("D3.M1()").WithLocation(4, 20),
                // (4,29): error CS9362: 'D3.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M2()").WithArguments("D3.M2()").WithLocation(4, 29),
                // (4,38): error CS9362: 'D3.M3()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M3()").WithArguments("D3.M3()").WithLocation(4, 38),
                // (4,47): error CS9362: 'D3.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M4()").WithArguments("D3.M4()").WithLocation(4, 47),
                // (4,56): error CS9362: 'D3.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M5()").WithArguments("D3.M5()").WithLocation(4, 56),
                // (4,65): error CS9362: 'D3.M6()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d3 = new D3(); d3.M1(); d3.M2(); d3.M3(); d3.M4(); d3.M5(); d3.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d3.M6()").WithArguments("D3.M6()").WithLocation(4, 65),
                // (5,20): error CS9362: 'C.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d4 = new D4(); d4.M1(); d4.M2(); d4.M3(); d4.M4(); d4.M5(); d4.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d4.M1()").WithArguments("C.M1()").WithLocation(5, 20),
                // (5,29): error CS9362: 'C.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d4 = new D4(); d4.M1(); d4.M2(); d4.M3(); d4.M4(); d4.M5(); d4.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d4.M2()").WithArguments("C.M2()").WithLocation(5, 29),
                // (5,47): error CS9362: 'C.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d4 = new D4(); d4.M1(); d4.M2(); d4.M3(); d4.M4(); d4.M5(); d4.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d4.M4()").WithArguments("C.M4()").WithLocation(5, 47),
                // (5,56): error CS9362: 'C.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // var d4 = new D4(); d4.M1(); d4.M2(); d4.M3(); d4.M4(); d4.M5(); d4.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "d4.M5()").WithArguments("C.M5()").WithLocation(5, 56),
                // (6,11): error CS9362: 'C.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M1()").WithArguments("C.M1()").WithLocation(6, 11),
                // (6,19): error CS9362: 'C.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M2()").WithArguments("C.M2()").WithLocation(6, 19),
                // (6,35): error CS9362: 'C.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M4()").WithArguments("C.M4()").WithLocation(6, 35),
                // (6,43): error CS9362: 'C.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C c = d1; c.M1(); c.M2(); c.M3(); c.M4(); c.M5(); c.M6();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.M5()").WithArguments("C.M5()").WithLocation(6, 43),
                // (10,33): error CS9364: Unsafe member 'C.M1()' cannot override safe member 'B.M1()'
                //     public extern override void M1();
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M1").WithArguments("C.M1()", "B.M1()").WithLocation(10, 33),
                // (12,33): error CS9364: Unsafe member 'C.M4()' cannot override safe member 'B.M4()'
                //     public extern override void M4();
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M4").WithArguments("C.M4()", "B.M4()").WithLocation(12, 33),
                // (24,31): error CS9362: 'C.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "base.M1()").WithArguments("C.M1()").WithLocation(24, 31),
                // (24,42): error CS9362: 'C.M2()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "base.M2()").WithArguments("C.M2()").WithLocation(24, 42),
                // (24,64): error CS9362: 'C.M4()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "base.M4()").WithArguments("C.M4()").WithLocation(24, 64),
                // (24,75): error CS9362: 'C.M5()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                //     public void BaseCalls() { base.M1(); base.M2(); base.M3(); base.M4(); base.M5(); base.M6(); }
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "base.M5()").WithArguments("C.M5()").WithLocation(24, 75),
                // (39,33): error CS9364: Unsafe member 'D3.M1()' cannot override safe member 'B.M1()'
                //     public extern override void M1();
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M1").WithArguments("D3.M1()", "B.M1()").WithLocation(39, 33),
                // (41,33): error CS9364: Unsafe member 'D3.M3()' cannot override safe member 'B.M3()'
                //     public extern override void M3();
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M3").WithArguments("D3.M3()", "B.M3()").WithLocation(41, 33),
                // (42,33): error CS9364: Unsafe member 'D3.M4()' cannot override safe member 'B.M4()'
                //     public extern override void M4();
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M4").WithArguments("D3.M4()", "B.M4()").WithLocation(42, 33),
                // (44,33): error CS9364: Unsafe member 'D3.M6()' cannot override safe member 'B.M6()'
                //     public extern override void M6();
                Diagnostic(ErrorCode.ERR_CallerUnsafeOverridingSafe, "M6").WithArguments("D3.M6()", "B.M6()").WithLocation(44, 33),
            ]);
    }
 
    [Fact]
    public void Extern_Method_Implementation()
    {
        CompileAndVerifyUnsafe(
            lib: """
                #pragma warning disable CS0626 // extern without attributes
                public interface I
                {
                    extern void M1();
                    void M2();
                }
                """,
            caller: """
                #pragma warning disable CS0626 // extern without attributes
                I i = new C1();
                i.M1();
                i.M2();
 
                public class C1 : I
                {
                    public void M1() { }
                    public void M2() { }
                }
 
                public class C2 : I
                {
                    void I.M1() { }
                    void I.M2() { }
                }
 
                public class C3 : I
                {
                    public unsafe void M1() { }
                    public unsafe void M2() { }
                }
 
                public class C4 : I
                {
                    unsafe void I.M1() { }
                    unsafe void I.M2() { }
                }
 
                public class C5 : I
                {
                    public extern void M1();
                    public extern void M2();
                }
 
                public class C6 : I
                {
                    extern void I.M1();
                    extern void I.M2();
                }
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            targetFramework: TargetFramework.Net100,
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["I.M1"],
            expectedSafeSymbols: ["I", "I.M2"],
            expectedNoAttributeInSource: ["I.M1"],
            expectedNoAttributeUnderLegacyRules: ["I.M1"],
            expectedDiagnostics:
            [
                // (3,1): error CS9362: 'I.M1()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // i.M1();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "i.M1()").WithArguments("I.M1()").WithLocation(3, 1),
                // (33,24): error CS9365: Unsafe member 'C5.M2()' cannot implicitly implement safe member 'I.M2()'
                //     public extern void M2();
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M2").WithArguments("C5.M2()", "I.M2()").WithLocation(33, 24),
                // (39,19): error CS9366: Unsafe member 'C6.I.M2()' cannot implement safe member 'I.M2()'
                //     extern void I.M2();
                Diagnostic(ErrorCode.ERR_CallerUnsafeExplicitlyImplementingSafe, "M2").WithArguments("C6.I.M2()", "I.M2()").WithLocation(39, 19),
            ],
            expectedDiagnosticsWhenReferencingLegacyLib:
            [
                // (32,24): error CS9365: Unsafe member 'C5.M1()' cannot implicitly implement safe member 'I.M1()'
                //     public extern void M1();
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M1").WithArguments("C5.M1()", "I.M1()").WithLocation(32, 24),
                // (33,24): error CS9365: Unsafe member 'C5.M2()' cannot implicitly implement safe member 'I.M2()'
                //     public extern void M2();
                Diagnostic(ErrorCode.ERR_CallerUnsafeImplicitlyImplementingSafe, "M2").WithArguments("C5.M2()", "I.M2()").WithLocation(33, 24),
                // (38,19): error CS9366: Unsafe member 'C6.I.M1()' cannot implement safe member 'I.M1()'
                //     extern void I.M1();
                Diagnostic(ErrorCode.ERR_CallerUnsafeExplicitlyImplementingSafe, "M1").WithArguments("C6.I.M1()", "I.M1()").WithLocation(38, 19),
                // (39,19): error CS9366: Unsafe member 'C6.I.M2()' cannot implement safe member 'I.M2()'
                //     extern void I.M2();
                Diagnostic(ErrorCode.ERR_CallerUnsafeExplicitlyImplementingSafe, "M2").WithArguments("C6.I.M2()", "I.M2()").WithLocation(39, 19),
            ]);
    }
 
    [Fact]
    public void Extern_LocalFunction()
    {
        var libSource = """
            #pragma warning disable CS0626 // extern without attributes
            #pragma warning disable CS8321 // unused local function
            public class C
            {
                public void M()
                {
                    static extern void F();
                }
            }
            """;
 
        var callerSource = """
            new C().M();
            """;
 
        object[] unsafeSymbols = ["C.<M>g__F|0_0"];
 
        CompileAndVerifyUnsafe(
            libSource,
            callerSource,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            optionsDll: TestOptions.UnsafeReleaseDll.WithMetadataImportOptions(MetadataImportOptions.All),
            verify: Verification.Skipped,
            expectedUnsafeSymbols: unsafeSymbols,
            expectedSafeSymbols: ["C"],
            expectedNoAttributeInSource: unsafeSymbols,
            expectedNoAttributeUnderLegacyRules: unsafeSymbols,
            skipSymbolsInSource: unsafeSymbols,
            expectedDiagnostics: []);
 
        CreateCompilation([libSource, callerSource],
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (7,28): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
            //         static extern void F();
            Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "F").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(7, 28));
 
        CreateCompilation([libSource, RequiresUnsafeAttributeDefinition],
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (7,28): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //         static extern void F();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "F").WithArguments("updated memory safety rules").WithLocation(7, 28));
 
        CreateCompilation(libSource,
            parseOptions: TestOptions.Regular14)
            .VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Extern_Property()
    {
        var libSource = """
            #pragma warning disable CS0626 // extern without attributes
            using System.Runtime.CompilerServices;
            using System.Runtime.InteropServices;
 
            public class C
            {
                public int P1 { set { } }
                public extern int P2 { set; }
                public static extern int P3 { [DllImport("test")] set; }
                public extern int P4 { [MethodImpl(MethodImplOptions.InternalCall)] set; }
            }
            """;
 
        var callerSource = """
            var c = new C();
            c.P1 = 0;
            c.P2 = 0;
            C.P3 = 0;
            c.P4 = 0;
            """;
 
        object[] unsafeSymbols = ["C.P2", "C.set_P2", "C.P3", "C.set_P3", "C.P4", "C.set_P4"];
 
        var commonDiagnostics = new[]
        {
            // (3,1): error CS9362: 'C.P2.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // c.P2 = 0;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C.P2.set").WithLocation(3, 1),
            // (4,1): error CS9362: 'C.P3.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // C.P3 = 0;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "C.P3").WithArguments("C.P3.set").WithLocation(4, 1),
            // (5,1): error CS9362: 'C.P4.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // c.P4 = 0;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P4").WithArguments("C.P4.set").WithLocation(5, 1),
        };
 
        CompileAndVerifyUnsafe(
            libSource,
            callerSource,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: unsafeSymbols,
            expectedSafeSymbols: ["C", "C.P1", "C.set_P1"],
            expectedNoAttributeInSource: unsafeSymbols,
            expectedNoAttributeUnderLegacyRules: unsafeSymbols,
            expectedDiagnostics: commonDiagnostics);
 
        CreateCompilation([libSource, callerSource],
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics([
                .. commonDiagnostics,
                // (8,23): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public extern int P2 { set; }
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "P2").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(8, 23),
                // (8,28): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public extern int P2 { set; }
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "set").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(8, 28),
                // (9,30): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public static extern int P3 { [DllImport("test")] set; }
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "P3").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(9, 30),
                // (9,55): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public static extern int P3 { [DllImport("test")] set; }
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "set").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(9, 55),
                // (10,23): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public extern int P4 { [MethodImpl(MethodImplOptions.InternalCall)] set; }
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "P4").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(10, 23),
                // (10,73): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public extern int P4 { [MethodImpl(MethodImplOptions.InternalCall)] set; }
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "set").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(10, 73),
            ]);
 
        CreateCompilation([libSource, RequiresUnsafeAttributeDefinition],
            parseOptions: TestOptions.Regular14,
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (8,23): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public extern int P2 { set; }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "P2").WithArguments("updated memory safety rules").WithLocation(8, 23),
            // (8,28): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public extern int P2 { set; }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "set").WithArguments("updated memory safety rules").WithLocation(8, 28),
            // (9,30): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public static extern int P3 { [DllImport("test")] set; }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "P3").WithArguments("updated memory safety rules").WithLocation(9, 30),
            // (9,55): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public static extern int P3 { [DllImport("test")] set; }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "set").WithArguments("updated memory safety rules").WithLocation(9, 55),
            // (10,23): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public extern int P4 { [MethodImpl(MethodImplOptions.InternalCall)] set; }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "P4").WithArguments("updated memory safety rules").WithLocation(10, 23),
            // (10,73): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public extern int P4 { [MethodImpl(MethodImplOptions.InternalCall)] set; }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "set").WithArguments("updated memory safety rules").WithLocation(10, 73));
 
        CreateCompilation(libSource,
            parseOptions: TestOptions.Regular14)
            .VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Extern_Property_WithPointers()
    {
        static string getLibSource(string modifiers) => $$"""
            #pragma warning disable CS0626 // extern without attributes
            public class C
            {
                public {{modifiers}} int* P { set; }
            }
            """;
 
        var callerSource = """
            var c = new C();
            c.P = null;
            """;
 
        var libUpdated = CreateCompilation(
            [getLibSource("extern"), RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libUpdatedRef = AsReference(libUpdated, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libUpdatedRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (2,1): error CS9362: 'C.P.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P = null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P").WithArguments("C.P.set").WithLocation(2, 1))
                .GetReferencedAssemblySymbol(libUpdatedRef);
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: ["C.P", "C.set_P"],
                expectedSafeSymbols: ["C"],
                expectedNoAttributeInSource: ["C.P", "C.set_P"]);
        }
 
        CreateCompilation(getLibSource("extern")).VerifyDiagnostics(
            // (4,19): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     public extern int* P { set; }
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(4, 19));
 
        // When compiling the lib under legacy rules, extern members are not unsafe, but members with pointers are.
        var libLegacy = CreateCompilation(
            getLibSource("unsafe extern"),
            options: TestOptions.UnsafeReleaseDll)
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libLegacyRef = AsReference(libLegacy, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libLegacyRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (2,1): error CS9363: 'C.P.set' must be used in an unsafe context because it has pointers in its signature
                // c.P = null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c.P").WithArguments("C.P.set").WithLocation(2, 1))
                .GetReferencedAssemblySymbol(libLegacyRef);
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: ["C.P", "C.set_P"],
                expectedSafeSymbols: ["C"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit);
        }
    }
 
    [Fact]
    public void Extern_Property_Explicit()
    {
        CompileAndVerifyUnsafe(
            lib: """
                #pragma warning disable CS0626 // extern without attributes
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public extern int P1 { set; }
                    public extern int P2 { [System.Runtime.CompilerServices.RequiresUnsafe] set; }
                }
                """,
            caller: """
                var c = new C();
                c.P1 = 0;
                c.P2 = 0;
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["C.P1", "C.set_P1", "C.P2", "C.set_P2"],
            expectedSafeSymbols: ["C"],
            expectedNoAttributeInSource: ["C.P2"],
            expectedNoAttributeUnderLegacyRules: ["C.P2"],
            expectedDiagnostics:
            [
                // (2,1): error CS9362: 'C.P1.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P1 = 0;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P1").WithArguments("C.P1.set").WithLocation(2, 1),
                // (3,1): error CS9362: 'C.P2.set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c.P2 = 0;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c.P2").WithArguments("C.P2.set").WithLocation(3, 1),
            ]);
    }
 
    [Fact]
    public void Extern_Indexer()
    {
        var libSource = """
            #pragma warning disable CS0626 // extern without attributes
            public class C
            {
                public extern int this[int i] { get; set; }
            }
            """;
 
        var callerSource = """
            var c = new C();
            c[0] = c[0] + 123;
            """;
 
        object[] unsafeSymbols = ["C.this[]", "C.get_Item", "C.set_Item"];
 
        var commonDiagnostics = new[]
        {
            // (2,1): error CS9362: 'C.this[int].set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // c[0] = c[0] + 123;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c[0]").WithArguments("C.this[int].set").WithLocation(2, 1),
            // (2,8): error CS9362: 'C.this[int].get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // c[0] = c[0] + 123;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c[0]").WithArguments("C.this[int].get").WithLocation(2, 8),
        };
 
        CompileAndVerifyUnsafe(
            libSource,
            callerSource,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: unsafeSymbols,
            expectedSafeSymbols: ["C"],
            expectedNoAttributeInSource: unsafeSymbols,
            expectedNoAttributeUnderLegacyRules: unsafeSymbols,
            expectedDiagnostics: commonDiagnostics);
 
        CreateCompilation([libSource, callerSource],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            [
                .. commonDiagnostics,
                // (4,23): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public extern int this[int i] { get; set; }
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "this").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(4, 23),
                // (4,37): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public extern int this[int i] { get; set; }
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "get").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(4, 37),
                // (4,42): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public extern int this[int i] { get; set; }
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "set").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(4, 42),
            ]);
 
        CreateCompilation([libSource, RequiresUnsafeAttributeDefinition],
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (4,23): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public extern int this[int i] { get; set; }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "this").WithArguments("updated memory safety rules").WithLocation(4, 23),
            // (4,37): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public extern int this[int i] { get; set; }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "get").WithArguments("updated memory safety rules").WithLocation(4, 37),
            // (4,42): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public extern int this[int i] { get; set; }
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "set").WithArguments("updated memory safety rules").WithLocation(4, 42));
 
        CreateCompilation(libSource,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseDll)
            .VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Extern_Indexer_WithPointers()
    {
        static string getLibSource(string modifiers) => $$"""
            #pragma warning disable CS0626 // extern without attributes
            public class C
            {
                public {{modifiers}} int* this[int i] { get; set; }
            }
            """;
 
        var callerSource = """
            var c = new C();
            c[0] = c[0] + 123;
            """;
 
        var libUpdated = CreateCompilation(
            [getLibSource("extern"), RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libUpdatedRef = AsReference(libUpdated, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libUpdatedRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (2,1): error CS9362: 'C.this[int].set' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c[0] = c[0] + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c[0]").WithArguments("C.this[int].set").WithLocation(2, 1),
                // (2,8): error CS9362: 'C.this[int].get' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c[0] = c[0] + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c[0]").WithArguments("C.this[int].get").WithLocation(2, 8))
                .GetReferencedAssemblySymbol(libUpdatedRef);
 
            object[] unsafeSymbols = ["C.this[]", "C.get_Item", "C.set_Item"];
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: unsafeSymbols,
                expectedSafeSymbols: ["C"],
                expectedNoAttributeInSource: unsafeSymbols);
        }
 
        CreateCompilation(getLibSource("extern")).VerifyDiagnostics(
            // (4,19): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     public extern int* P { set; }
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(4, 19));
 
        // When compiling the lib under legacy rules, extern members are not unsafe, but members with pointers are.
        var libLegacy = CreateCompilation(
            getLibSource("unsafe extern"),
            options: TestOptions.UnsafeReleaseDll)
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libLegacyRef = AsReference(libLegacy, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libLegacyRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (2,1): error CS9363: 'C.this[int].set' must be used in an unsafe context because it has pointers in its signature
                // c[0] = c[0] + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c[0]").WithArguments("C.this[int].set").WithLocation(2, 1),
                // (2,8): error CS9363: 'C.this[int].get' must be used in an unsafe context because it has pointers in its signature
                // c[0] = c[0] + 123;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c[0]").WithArguments("C.this[int].get").WithLocation(2, 8))
                .GetReferencedAssemblySymbol(libLegacyRef);
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: ["C.this[]", "C.get_Item", "C.set_Item"],
                expectedSafeSymbols: ["C"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit);
        }
    }
 
    [Fact]
    public void Extern_Indexer_Explicit()
    {
        CompileAndVerifyUnsafe(
            lib: """
                #pragma warning disable CS0626 // extern without attributes
                public class C1
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public extern int this[int i] { set; }
                }
                public class C2
                {
                    public extern int this[int i] { [System.Runtime.CompilerServices.RequiresUnsafe] set; }
                }
                """,
            caller: """
                new C1()[0] = 0;
                new C2()[0] = 0;
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["C1.this[]", "C1.set_Item", "C2.this[]", "C2.set_Item"],
            expectedSafeSymbols: ["C1", "C2"],
            expectedNoAttributeInSource: ["C2.this[]"],
            expectedNoAttributeUnderLegacyRules: ["C2.this[]"],
            expectedDiagnostics:
            [
                // (1,1): error CS9362: 'C1.this[int].set' must be used in an unsafe context because it is marked as 'unsafe' or 'extern'
                // new C1()[0] = 0;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C1()[0]").WithArguments("C1.this[int].set").WithLocation(1, 1),
                // (2,1): error CS9362: 'C2.this[int].set' must be used in an unsafe context because it is marked as 'unsafe' or 'extern'
                // new C2()[0] = 0;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C2()[0]").WithArguments("C2.this[int].set").WithLocation(2, 1),
            ]);
    }
 
    [Fact]
    public void Extern_Event()
    {
        var libSource = """
            #pragma warning disable CS0067 // unused event
            public class C
            {
                [method: System.Runtime.InteropServices.DllImport("test")]
                public static extern event System.Action E;
            }
            """;
 
        var callerSource = """
            C.E += null;
            """;
 
        object[] unsafeSymbols = ["C.E", "C.add_E", "C.remove_E"];
 
        var commonDiagnostics = new[]
        {
            // (1,5): error CS9362: 'C.E.add' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // C.E += null;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "+=").WithArguments("C.E.add").WithLocation(1, 5),
        };
 
        CompileAndVerifyUnsafe(
            libSource,
            callerSource,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: unsafeSymbols,
            expectedSafeSymbols: ["C"],
            expectedNoAttributeInSource: unsafeSymbols,
            expectedNoAttributeUnderLegacyRules: unsafeSymbols,
            expectedDiagnostics: commonDiagnostics);
 
        CreateCompilation([libSource, callerSource],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics([
                .. commonDiagnostics,
                // (5,46): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public static extern event System.Action E;
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "E").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(5, 46),
                // (5,46): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public static extern event System.Action E;
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "E").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(5, 46),
                // (5,46): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public static extern event System.Action E;
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "E").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(5, 46),
            ]);
 
        CreateCompilation([libSource, RequiresUnsafeAttributeDefinition],
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (5,46): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public static extern event System.Action E;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "E").WithArguments("updated memory safety rules").WithLocation(5, 46),
            // (5,46): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public static extern event System.Action E;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "E").WithArguments("updated memory safety rules").WithLocation(5, 46),
            // (5,46): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public static extern event System.Action E;
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "E").WithArguments("updated memory safety rules").WithLocation(5, 46));
 
        CreateCompilation(libSource,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseDll)
            .VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Extern_Event_WithPointers()
    {
        var libSource = """
            #pragma warning disable CS0067 // unused event
            public class C
            {
                [method: System.Runtime.InteropServices.DllImport("test")]
                public static extern event System.Action<int*[]> E;
            }
            """;
 
        var callerSource = """
            C.E += null;
            """;
 
        var libUpdated = CreateCompilation(
            [libSource, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libUpdatedRef = AsReference(libUpdated, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libUpdatedRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (1,5): error CS9362: 'C.E.add' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C.E += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "+=").WithArguments("C.E.add").WithLocation(1, 5))
                .GetReferencedAssemblySymbol(libUpdatedRef);
 
            object[] unsafeSymbols = ["C.E", "C.add_E", "C.remove_E"];
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: unsafeSymbols,
                expectedSafeSymbols: ["C"],
                expectedNoAttributeInSource: unsafeSymbols);
        }
 
        // When compiling the lib under legacy rules, extern members are not unsafe, but members with pointers are.
        // https://github.com/dotnet/roslyn/issues/81944: There is no error for the pointer even though `unsafe` is missing.
        var libLegacy = CreateCompilation(
            libSource)
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libLegacyRef = AsReference(libLegacy, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libLegacyRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (1,5): error CS9363: 'C.E.add' must be used in an unsafe context because it has pointers in its signature
                // C.E += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "+=").WithArguments("C.E.add").WithLocation(1, 5))
                .GetReferencedAssemblySymbol(libLegacyRef);
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: ["C.E", "C.add_E", "C.remove_E"],
                expectedSafeSymbols: ["C"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit);
        }
    }
 
    [Fact]
    public void Extern_Event_Explicit()
    {
        CompileAndVerifyUnsafe(
            lib: """
                #pragma warning disable CS0626 // extern without attributes
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public static extern event System.Action E;
                }
                """,
            caller: """
                C.E += null;
                C.E -= null;
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["C.E", "C.add_E", "C.remove_E"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,5): error CS9362: 'C.E.add' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C.E += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "+=").WithArguments("C.E.add").WithLocation(1, 5),
                // (2,5): error CS9362: 'C.E.remove' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // C.E -= null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "-=").WithArguments("C.E.remove").WithLocation(2, 5),
            ]);
    }
 
    [Fact]
    public void Extern_Constructor()
    {
        var libSource = """
            #pragma warning disable CS0824 // extern constructor
            public class C
            {
                public extern C();
            }
            """;
 
        var callerSource = """
            _ = new C();
            """;
 
        object[] unsafeSymbols = ["C..ctor"];
 
        var commonDiagnostics = new[]
        {
            // (1,5): error CS9362: 'C.C()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // _ = new C();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C()").WithArguments("C.C()").WithLocation(1, 5),
        };
 
        CompileAndVerifyUnsafe(
            libSource,
            callerSource,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: unsafeSymbols,
            expectedSafeSymbols: ["C"],
            expectedNoAttributeInSource: unsafeSymbols,
            expectedNoAttributeUnderLegacyRules: unsafeSymbols,
            expectedDiagnostics: commonDiagnostics);
 
        CreateCompilation([libSource, callerSource],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics([
                .. commonDiagnostics,
                // (4,19): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public extern C();
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "C").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(4, 19),
            ]);
 
        CreateCompilation([libSource, RequiresUnsafeAttributeDefinition],
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (4,19): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public extern C();
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "C").WithArguments("updated memory safety rules").WithLocation(4, 19));
 
        CreateCompilation(libSource,
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseDll)
            .VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Extern_Constructor_WithPointers()
    {
        static string getLibSource(string modifiers) => $$"""
            #pragma warning disable CS0824 // extern constructor
            public class C
            {
                public {{modifiers}} C(int* p);
            }
            """;
 
        var callerSource = """
            _ = new C(null);
            """;
 
        var libUpdated = CreateCompilation(
            [getLibSource("extern"), RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libUpdatedRef = AsReference(libUpdated, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libUpdatedRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (1,5): error CS9362: 'C.C(int*)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = new C(null);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C(null)").WithArguments("C.C(int*)").WithLocation(1, 5))
                .GetReferencedAssemblySymbol(libUpdatedRef);
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: ["C..ctor"],
                expectedSafeSymbols: ["C"],
                expectedNoAttributeInSource: ["C..ctor"]);
        }
 
        CreateCompilation(getLibSource("extern")).VerifyDiagnostics(
            // (4,21): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     public extern C(int* p);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(4, 21));
 
        // When compiling the lib under legacy rules, extern members are not unsafe, but members with pointers are.
        var libLegacy = CreateCompilation(
            getLibSource("unsafe extern"),
            options: TestOptions.UnsafeReleaseDll)
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libLegacyRef = AsReference(libLegacy, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libLegacyRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (1,5): error CS9363: 'C.C(int*)' must be used in an unsafe context because it has pointers in its signature
                // _ = new C(null);
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "new C(null)").WithArguments("C.C(int*)").WithLocation(1, 5))
                .GetReferencedAssemblySymbol(libLegacyRef);
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: ["C..ctor"],
                expectedSafeSymbols: ["C"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit);
        }
    }
 
    [Fact]
    public void Extern_Constructor_Explicit()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public extern C();
                }
                """,
            caller: """
                _ = new C();
                """,
            additionalSources: [RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["C..ctor"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (1,5): error CS9362: 'C.C()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // _ = new C();
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C()").WithArguments("C.C()").WithLocation(1, 5),
            ]);
    }
 
    [Fact]
    public void Extern_Operator()
    {
        var libSource = """
            #pragma warning disable CS0626 // extern without attributes
            public class C
            {
                public extern void operator +=(C c);
            }
            """;
 
        var callerSource = """
            var c = new C();
            c += c;
            """;
 
        object[] unsafeSymbols = ["C.op_AdditionAssignment"];
 
        var commonDiagnostics = new[]
        {
            // (2,1): error CS9362: 'C.operator +=(C)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // c += c;
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c += c").WithArguments("C.operator +=(C)").WithLocation(2, 1),
        };
 
        CompileAndVerifyUnsafe(
            libSource,
            callerSource,
            additionalSources: [CompilerFeatureRequiredAttribute, RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: unsafeSymbols,
            expectedSafeSymbols: ["C"],
            expectedNoAttributeInSource: unsafeSymbols,
            expectedNoAttributeUnderLegacyRules: unsafeSymbols,
            expectedDiagnostics: commonDiagnostics);
 
        CreateCompilation([libSource, callerSource, CompilerFeatureRequiredAttribute],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics([
                .. commonDiagnostics,
                // (4,33): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiresUnsafeAttribute..ctor'
                //     public extern void operator +=(C c);
                Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "+=").WithArguments("System.Runtime.CompilerServices.RequiresUnsafeAttribute", ".ctor").WithLocation(4, 33),
            ]);
 
        CreateCompilation([libSource, CompilerFeatureRequiredAttribute, RequiresUnsafeAttributeDefinition],
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (4,33): error CS8652: The feature 'updated memory safety rules' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
            //     public extern void operator +=(C c);
            Diagnostic(ErrorCode.ERR_FeatureInPreview, "+=").WithArguments("updated memory safety rules").WithLocation(4, 33));
 
        CreateCompilation([libSource, CompilerFeatureRequiredAttribute],
            parseOptions: TestOptions.Regular14,
            options: TestOptions.UnsafeReleaseDll)
            .VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void Extern_Operator_WithPointers()
    {
        static string getLibSource(string modifiers) => $$"""
            #pragma warning disable CS0626 // extern without attributes
            public class C
            {
                public {{modifiers}} void operator +=(int* p);
            }
            """;
 
        var callerSource = """
            var c = new C();
            c += null;
            """;
 
        var libUpdated = CreateCompilation(
            [getLibSource("extern"), CompilerFeatureRequiredAttribute, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libUpdatedRef = AsReference(libUpdated, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libUpdatedRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (2,1): error CS9362: 'C.operator +=(int*)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c += null").WithArguments("C.operator +=(int*)").WithLocation(2, 1))
                .GetReferencedAssemblySymbol(libUpdatedRef);
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: ["C.op_AdditionAssignment"],
                expectedSafeSymbols: ["C"],
                expectedNoAttributeInSource: ["C.op_AdditionAssignment"]);
        }
 
        CreateCompilation([getLibSource("extern"), CompilerFeatureRequiredAttribute]).VerifyDiagnostics(
            // (4,36): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
            //     public extern void operator +=(int* p);
            Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(4, 36));
 
        // When compiling the lib under legacy rules, extern members are not unsafe, but members with pointers are.
        var libLegacy = CreateCompilation(
            [getLibSource("unsafe extern"), CompilerFeatureRequiredAttribute],
            options: TestOptions.UnsafeReleaseDll)
            .VerifyDiagnostics();
 
        foreach (var useCompilationReference in new[] { false, true })
        {
            var libLegacyRef = AsReference(libLegacy, useCompilationReference);
 
            var libAssemblySymbol = CreateCompilation(callerSource,
                [libLegacyRef],
                options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules())
                .VerifyDiagnostics(
                // (2,1): error CS9363: 'C.operator +=(int*)' must be used in an unsafe context because it has pointers in its signature
                // c += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperationCompat, "c += null").WithArguments("C.operator +=(int*)").WithLocation(2, 1))
                .GetReferencedAssemblySymbol(libLegacyRef);
 
            VerifyRequiresUnsafeAttribute(
                libAssemblySymbol.Modules.Single(),
                expectedUnsafeSymbols: ["C.op_AdditionAssignment"],
                expectedSafeSymbols: ["C"],
                expectedUnsafeMode: CallerUnsafeMode.Implicit);
        }
    }
 
    [Fact]
    public void Extern_Operator_Explicit()
    {
        CompileAndVerifyUnsafe(
            lib: """
                public class C
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    public extern void operator +=(C c);
                }
                """,
            caller: """
                var c = new C();
                c += null;
                """,
            additionalSources: [CompilerFeatureRequiredAttribute, RequiresUnsafeAttributeDefinition],
            verify: Verification.Skipped,
            expectedUnsafeSymbols: ["C.op_AdditionAssignment"],
            expectedSafeSymbols: ["C"],
            expectedDiagnostics:
            [
                // (2,1): error CS9362: 'C.operator +=(C)' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
                // c += null;
                Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "c += null").WithArguments("C.operator +=(C)").WithLocation(2, 1),
            ]);
    }
 
    [Fact]
    public void RequiresUnsafeAttribute_Applied()
    {
        var source = """
            class C
            {
                [System.Runtime.CompilerServices.RequiresUnsafe]
                void M1() { }
                void M2() { }
            }
            """;
 
        var expectedDiagnostics = new[]
        {
            // (3,6): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "System.Runtime.CompilerServices.RequiresUnsafe").WithLocation(3, 6),
        };
 
        CreateCompilation([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithWarningLevel(10))
            .VerifyEmitDiagnostics();
        CreateCompilation([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithWarningLevel(11))
            .VerifyEmitDiagnostics(expectedDiagnostics);
 
        CompileAndVerify([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithMetadataImportOptions(MetadataImportOptions.All),
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: ["C.M1"],
                expectedSafeSymbols: ["C", "C.M2"],
                expectedUnsafeMode: CallerUnsafeMode.None))
            .VerifyDiagnostics(expectedDiagnostics);
 
        var ref1 = CompileAndVerify([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules().WithMetadataImportOptions(MetadataImportOptions.All),
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: ["C.M1"],
                expectedSafeSymbols: ["C", "C.M2"]))
            .VerifyDiagnostics()
            .GetImageReference();
 
        CompileAndVerify("", [ref1],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules().WithMetadataImportOptions(MetadataImportOptions.All),
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: [],
                expectedSafeSymbols: []))
            .VerifyDiagnostics();
 
        var source2 = """
            class B
            {
                void M3() { }
                [System.Runtime.CompilerServices.RequiresUnsafe]
                void M4() { }
            }
            """;
 
        CompileAndVerify(source2, [ref1],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules().WithMetadataImportOptions(MetadataImportOptions.All),
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: ["B.M4"],
                expectedSafeSymbols: ["B", "B.M3"]))
            .VerifyDiagnostics();
 
        CompileAndVerify([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.ReleaseModule.WithAllowUnsafe(true).WithMetadataImportOptions(MetadataImportOptions.All),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: ["C.M1"],
                expectedSafeSymbols: ["C", "C.M2"],
                expectedUnsafeMode: CallerUnsafeMode.None))
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation([source, MemorySafetyRulesAttributeDefinition],
            options: TestOptions.ReleaseModule.WithAllowUnsafe(true).WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,38): error CS0234: The type or namespace name 'RequiresUnsafeAttribute' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)
            //     [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "RequiresUnsafe").WithArguments("RequiresUnsafeAttribute", "System.Runtime.CompilerServices").WithLocation(3, 38),
            // (3,38): error CS0234: The type or namespace name 'RequiresUnsafe' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)
            //     [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "RequiresUnsafe").WithArguments("RequiresUnsafe", "System.Runtime.CompilerServices").WithLocation(3, 38));
    }
 
    [Fact]
    public void RequiresUnsafeAttribute_NotApplied()
    {
        var source = """
            public class C
            {
                public void M() { }
            }
            """;
 
        CompileAndVerify(source,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: [],
                expectedSafeSymbols: ["C", "C.M"]))
            .VerifyDiagnostics();
 
        CompileAndVerify(source,
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: [],
                expectedSafeSymbols: ["C", "C.M"]))
            .VerifyDiagnostics();
 
        CompileAndVerify([source, MemorySafetyRulesAttributeDefinition],
            options: TestOptions.ReleaseModule.WithUpdatedMemorySafetyRules(),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: [],
                expectedSafeSymbols: ["C", "C.M"]))
            .VerifyDiagnostics();
    }
 
    [Fact]
    public void RequiresUnsafeAttribute_LocalFunction()
    {
        var source = """
            #pragma warning disable CS8321 // Local function is declared but never used
            class C
            {
                void M()
                {
                    [System.Runtime.CompilerServices.RequiresUnsafe]
                    void M1() { }
                    void M2() { }
                }
            }
            """;
 
        var m1 = "C.<M>g__M1|0_0";
        var m2 = "C.<M>g__M2|0_1";
 
        var expectedDiagnostics = new[]
        {
            // (6,10): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //         [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "System.Runtime.CompilerServices.RequiresUnsafe").WithLocation(6, 10),
        };
 
        CompileAndVerify([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithMetadataImportOptions(MetadataImportOptions.All),
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: [m1],
                expectedSafeSymbols: [m2],
                expectedUnsafeMode: CallerUnsafeMode.None))
            .VerifyDiagnostics(expectedDiagnostics);
 
        CompileAndVerify([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules().WithMetadataImportOptions(MetadataImportOptions.All),
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: [m1],
                expectedSafeSymbols: [m2]))
            .VerifyDiagnostics();
 
        CompileAndVerify([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.ReleaseModule.WithAllowUnsafe(true).WithMetadataImportOptions(MetadataImportOptions.All),
            verify: Verification.Skipped,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: [m1],
                expectedSafeSymbols: [m2],
                expectedUnsafeMode: CallerUnsafeMode.None))
            .VerifyDiagnostics(expectedDiagnostics);
 
        CreateCompilation([source, MemorySafetyRulesAttributeDefinition],
            options: TestOptions.ReleaseModule.WithAllowUnsafe(true).WithUpdatedMemorySafetyRules())
            .VerifyEmitDiagnostics(
            // (6,42): error CS0234: The type or namespace name 'RequiresUnsafeAttribute' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)
            //         [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "RequiresUnsafe").WithArguments("RequiresUnsafeAttribute", "System.Runtime.CompilerServices").WithLocation(6, 42),
            // (6,42): error CS0234: The type or namespace name 'RequiresUnsafe' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?)
            //         [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "RequiresUnsafe").WithArguments("RequiresUnsafe", "System.Runtime.CompilerServices").WithLocation(6, 42));
    }
 
    [Fact]
    public void RequiresUnsafeAttribute_Reflection()
    {
        var sourceA = """
            using System;
            using System.Linq;
            using System.Reflection;
            public class A
            {
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public void M1() { }
                public void M2() { }
                public static void RequiresUnsafe(MethodInfo method)
                {
                    var count = method.GetCustomAttributes(inherit: false).Count(a => a.GetType().Name == "RequiresUnsafeAttribute");
                    Console.Write(count);
                }
            }
            """;
        var refA = CreateCompilation([sourceA, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics()
            .EmitToImageReference();
 
        var sourceB = """
            class B : A
            {
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public void M3() { }
                public void M4() { }
                static void Main()
                {
                    RequiresUnsafe(typeof(A).GetMethod("M1"));
                    RequiresUnsafe(typeof(A).GetMethod("M2"));
                    RequiresUnsafe(typeof(B).GetMethod("M3"));
                    RequiresUnsafe(typeof(B).GetMethod("M4"));
                }
            }
            """;
        CompileAndVerify(sourceB, [refA],
            options: TestOptions.UnsafeReleaseExe.WithUpdatedMemorySafetyRules(),
            expectedOutput: "1010")
            .VerifyDiagnostics();
    }
 
    [Fact]
    public void RequiresUnsafeAttribute_FromSource()
    {
        var source = """
            public class C
            {
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public void M() { }
            }
            """;
 
        CompileAndVerify([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: ["C.M"],
                expectedSafeSymbols: ["C"],
                expectedUnsafeMode: CallerUnsafeMode.None))
            .VerifyDiagnostics(
            // (3,6): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "System.Runtime.CompilerServices.RequiresUnsafe").WithLocation(3, 6));
 
        CompileAndVerify([source, RequiresUnsafeAttributeDefinition],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: ["C.M"],
                expectedSafeSymbols: ["C"]))
            .VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void RequiresUnsafeAttribute_FromMetadata(bool useCompilationReference)
    {
        var comp = CreateCompilation(RequiresUnsafeAttributeDefinition);
        CompileAndVerify(comp,
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: [],
                expectedSafeSymbols: [AttributeDescription.RequiresUnsafeAttribute.FullName]))
            .VerifyDiagnostics();
        var ref1 = AsReference(comp, useCompilationReference);
 
        var source = """
            public class C
            {
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public void M() { }
            }
            """;
 
        CompileAndVerify(source, [ref1],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules(),
            symbolValidator: m => VerifyRequiresUnsafeAttribute(
                m,
                expectedUnsafeSymbols: ["C.M"],
                expectedSafeSymbols: ["C"]))
            .VerifyDiagnostics();
    }
 
    [Theory, CombinatorialData]
    public void RequiresUnsafeAttribute_FromMetadata_Multiple(bool useCompilationReference)
    {
        var comp1 = CreateCompilation(RequiresUnsafeAttributeDefinition, assemblyName: "lib1").VerifyDiagnostics();
        var ref1 = AsReference(comp1, useCompilationReference);
 
        var comp2 = CreateCompilation(RequiresUnsafeAttributeDefinition, assemblyName: "lib2").VerifyDiagnostics();
        var ref2 = AsReference(comp2, useCompilationReference);
 
        var source = """
            public class C
            {
                [System.Runtime.CompilerServices.RequiresUnsafe]
                public void M() { }
            }
            """;
 
        // Ambiguous attribute definitions from references.
        CreateCompilation(source, [ref1, ref2],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,38): error CS0433: The type 'RequiresUnsafeAttribute' exists in both 'lib1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'lib2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
            //     [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.ERR_SameFullNameAggAgg, "RequiresUnsafe").WithArguments("lib1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "System.Runtime.CompilerServices.RequiresUnsafeAttribute", "lib2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(3, 38));
 
        // Also defined in source.
        var lib = CreateCompilation([source, RequiresUnsafeAttributeDefinition], [ref1, ref2],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (3,38): warning CS0436: The type 'RequiresUnsafeAttribute' in '' conflicts with the imported type 'RequiresUnsafeAttribute' in 'lib1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in ''.
            //     [System.Runtime.CompilerServices.RequiresUnsafe]
            Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "RequiresUnsafe").WithArguments("", "System.Runtime.CompilerServices.RequiresUnsafeAttribute", "lib1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "System.Runtime.CompilerServices.RequiresUnsafeAttribute").WithLocation(3, 38));
 
        CreateCompilation("""
            new C().M();
            """,
            [AsReference(lib, useCompilationReference)],
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS9362: 'C.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // new C().M();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C().M()").WithArguments("C.M()").WithLocation(1, 1));
    }
 
    [Theory, CombinatorialData]
    public void RequiresUnsafeAttribute_FromMetadata_Multiple_AndCorLib(bool useCompilationReference)
    {
        var corlibSource = """
            namespace System
            {
                public class Object;
                public class ValueType;
                public class String;
                public class Attribute;
                public struct Void;
                public struct Int32;
                public struct Boolean;
                public class AttributeUsageAttribute
                {
                    public AttributeUsageAttribute(AttributeTargets t) { }
                    public bool AllowMultiple { get; set; }
                    public bool Inherited { get; set; }
                }
                public class Enum;
                public enum AttributeTargets;
            }
 
            namespace System.Runtime.CompilerServices
            {
                public sealed class RequiresUnsafeAttribute : Attribute;
            }
            """;
 
        var corlib = CreateEmptyCompilation(corlibSource, assemblyName: "corlib").VerifyDiagnostics();
        var corlibRef = AsReference(corlib, useCompilationReference);
 
        var comp1 = CreateEmptyCompilation("", [corlibRef], assemblyName: "lib1").VerifyDiagnostics();
        var ref1 = AsReference(comp1, useCompilationReference);
 
        var comp2 = CreateEmptyCompilation("", [corlibRef], assemblyName: "lib2").VerifyDiagnostics();
        var ref2 = AsReference(comp2, useCompilationReference);
 
        var source = """
            #pragma warning disable CS0626 // extern without attributes
            public class C
            {
                public extern void M();
            }
            """;
 
        // Using the attribute from corlib even if there are ambiguous definitions in other references.
        var lib = CreateEmptyCompilation(source, [ref1, ref2, corlibRef],
            options: TestOptions.UnsafeReleaseDll.WithUpdatedMemorySafetyRules()
                .WithSpecificDiagnosticOptions([KeyValuePair.Create("CS8021", ReportDiagnostic.Suppress)]))
            .VerifyDiagnostics();
 
        CreateEmptyCompilation("""
            new C().M();
            """,
            [AsReference(lib, useCompilationReference), ref1, ref2, corlibRef],
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS9362: 'C.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // new C().M();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "new C().M()").WithArguments("C.M()").WithLocation(1, 1));
    }
 
    [Fact]
    public void RequiresUnsafeAttribute_FromMetadata_UnrecognizedConstructor()
    {
        // [module: MemorySafetyRules(2)]
        // public class A
        // {
        //     [RequiresUnsafe(1), RequiresUnsafe(0)]
        //     public static void M() => throw null;
        // }
        var sourceA = $$"""
            .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
            .assembly '<<GeneratedFileName>>' { }
            .module '<<GeneratedFileName>>.dll'
            .custom instance void System.Runtime.CompilerServices.MemorySafetyRulesAttribute::.ctor(int32) = { int32({{CSharpCompilationOptions.UpdatedMemorySafetyRulesVersion}}) }
            .class private System.Runtime.CompilerServices.MemorySafetyRulesAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
            }
            .class private System.Runtime.CompilerServices.RequiresUnsafeAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
            }
            .class public A
            {
                .method public static void M()
                {
                    .custom instance void System.Runtime.CompilerServices.RequiresUnsafeAttribute::.ctor(int32) = { int32(1) }
                    .custom instance void System.Runtime.CompilerServices.RequiresUnsafeAttribute::.ctor(int32) = { int32(0) }
                    ldnull throw
                }
            }
            """;
        var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
        var a = CreateCompilation("", [refA]).VerifyDiagnostics().GetReferencedAssemblySymbol(refA);
        Assert.Equal(CallerUnsafeMode.None, a.GlobalNamespace.GetMember("A.M").CallerUnsafeMode);
 
        var sourceB = """
            A.M();
            """;
        CreateCompilation(sourceB, [refA],
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void RequiresUnsafeAttribute_FromMetadata_UnrecognizedAndRecognizedConstructor()
    {
        // [module: MemorySafetyRules(2)]
        // public class A
        // {
        //     [RequiresUnsafe(1), RequiresUnsafe()]
        //     public static void M() => throw null;
        // }
        var sourceA = $$"""
            .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
            .assembly '<<GeneratedFileName>>' { }
            .module '<<GeneratedFileName>>.dll'
            .custom instance void System.Runtime.CompilerServices.MemorySafetyRulesAttribute::.ctor(int32) = { int32({{CSharpCompilationOptions.UpdatedMemorySafetyRulesVersion}}) }
            .class private System.Runtime.CompilerServices.MemorySafetyRulesAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
            }
            .class private System.Runtime.CompilerServices.RequiresUnsafeAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
            }
            .class public A
            {
                .method public static void M()
                {
                    .custom instance void System.Runtime.CompilerServices.RequiresUnsafeAttribute::.ctor(int32) = { int32(1) }
                    .custom instance void System.Runtime.CompilerServices.RequiresUnsafeAttribute::.ctor()
                    ldnull throw
                }
            }
            """;
        var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
        var a = CreateCompilation("", [refA]).VerifyDiagnostics().GetReferencedAssemblySymbol(refA);
        Assert.Equal(CallerUnsafeMode.Explicit, a.GlobalNamespace.GetMember("A.M").CallerUnsafeMode);
 
        var sourceB = """
            A.M();
            """;
        CreateCompilation(sourceB, [refA],
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS9362: 'A.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // A.M();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "A.M()").WithArguments("A.M()").WithLocation(1, 1));
    }
 
    [Fact]
    public void RequiresUnsafeAttribute_FromMetadata_AppliedMultipleTimes()
    {
        // [module: MemorySafetyRules(2)]
        // public class A
        // {
        //     [RequiresUnsafe, RequiresUnsafe]
        //     public static void M() => throw null;
        // }
        var sourceA = $$"""
            .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
            .assembly '<<GeneratedFileName>>' { }
            .module '<<GeneratedFileName>>.dll'
            .custom instance void System.Runtime.CompilerServices.MemorySafetyRulesAttribute::.ctor(int32) = { int32({{CSharpCompilationOptions.UpdatedMemorySafetyRulesVersion}}) }
            .class private System.Runtime.CompilerServices.MemorySafetyRulesAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor(int32 version) cil managed { ret }
            }
            .class private System.Runtime.CompilerServices.RequiresUnsafeAttribute extends [mscorlib]System.Attribute
            {
                .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret }
            }
            .class public A
            {
                .method public static void M()
                {
                    .custom instance void System.Runtime.CompilerServices.RequiresUnsafeAttribute::.ctor()
                    .custom instance void System.Runtime.CompilerServices.RequiresUnsafeAttribute::.ctor()
                    ldnull throw
                }
            }
            """;
        var refA = CompileIL(sourceA, prependDefaultHeader: false);
 
        var a = CreateCompilation("", [refA]).VerifyDiagnostics().GetReferencedAssemblySymbol(refA);
        Assert.Equal(CallerUnsafeMode.Explicit, a.GlobalNamespace.GetMember("A.M").CallerUnsafeMode);
 
        var sourceB = """
            A.M();
            """;
        CreateCompilation(sourceB, [refA],
            options: TestOptions.ReleaseExe.WithUpdatedMemorySafetyRules())
            .VerifyDiagnostics(
            // (1,1): error CS9362: 'A.M()' must be used in an unsafe context because it is marked as 'RequiresUnsafe' or 'extern'
            // A.M();
            Diagnostic(ErrorCode.ERR_UnsafeMemberOperation, "A.M()").WithArguments("A.M()").WithLocation(1, 1));
    }
 
    [Theory, CombinatorialData]
    public void RequiresUnsafeAttribute_ReferencedInSource(
        bool updatedRules,
        bool useCompilationReference)
    {
        var comp1 = CreateCompilation("""
            namespace System.Runtime.CompilerServices
            {
                public sealed class RequiresUnsafeAttribute : Attribute;
            }
            """).VerifyDiagnostics();
        var ref1 = AsReference(comp1, useCompilationReference);
 
        CSharpTestSource source =
        [
            """
            using System.Runtime.CompilerServices;
            [RequiresUnsafeAttribute] class C
            {
                [RequiresUnsafeAttribute] void M() { }
                [RequiresUnsafeAttribute] int P1 { get; set; }
                [field: RequiresUnsafeAttribute] int P2 { get; set; }
                int P3 { [RequiresUnsafeAttribute] get; [RequiresUnsafeAttribute] set; }
            #pragma warning disable CS0067 // unused event
                [RequiresUnsafeAttribute] event System.Action E1;
                [field: RequiresUnsafeAttribute] event System.Action E2;
                event System.Action E3 { [RequiresUnsafeAttribute] add { } [RequiresUnsafeAttribute] remove { } }
                [RequiresUnsafeAttribute] int this[int i] { get => i; set { } }
                [RequiresUnsafeAttribute] C() { }
                [RequiresUnsafeAttribute] ~C() { }
                [RequiresUnsafeAttribute] static C() { }
                [RequiresUnsafeAttribute] public static C operator +(C c1, C c2) => c1;
                [RequiresUnsafeAttribute] public void operator +=(C c) { }
                public void M([RequiresUnsafeAttribute] int x) { }
                [return: RequiresUnsafeAttribute] public int Func() => 0;
                public void M<[RequiresUnsafeAttribute] T>() { }
            #pragma warning disable CS0169 // unused field
                [RequiresUnsafeAttribute] int F;
                void L() { var lam = [RequiresUnsafeAttribute] () => { }; }
            }
            [RequiresUnsafeAttribute] delegate void D();
            [RequiresUnsafeAttribute] enum E { X }
            """, """
            using System.Runtime.CompilerServices;
            [module: RequiresUnsafeAttribute]
            [assembly: RequiresUnsafeAttribute]
            """,
            CompilerFeatureRequiredAttribute,
        ];
 
        var commonErrors = new[]
        {
            // (14,6): error CS9367: RequiresUnsafeAttribute cannot be applied to this symbol.
            //     [RequiresUnsafeAttribute] ~C() { }
            Diagnostic(ErrorCode.ERR_RequiresUnsafeAttributeUnsupportedMemberTarget, "RequiresUnsafeAttribute").WithLocation(14, 6),
            // (15,6): error CS9367: RequiresUnsafeAttribute cannot be applied to this symbol.
            //     [RequiresUnsafeAttribute] static C() { }
            Diagnostic(ErrorCode.ERR_RequiresUnsafeAttributeUnsupportedMemberTarget, "RequiresUnsafeAttribute").WithLocation(15, 6),
            // (23,27): error CS9367: RequiresUnsafeAttribute cannot be applied to this symbol.
            //     void L() { var lam = [RequiresUnsafeAttribute] () => { }; }
            Diagnostic(ErrorCode.ERR_RequiresUnsafeAttributeUnsupportedMemberTarget, "RequiresUnsafeAttribute").WithLocation(23, 27),
        };
 
        var commonWarnings = new[]
        {
            // (4,6): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     [RequiresUnsafeAttribute] void M() { }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "RequiresUnsafeAttribute").WithLocation(4, 6),
            // (7,15): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     int P3 { [RequiresUnsafeAttribute] get; [RequiresUnsafeAttribute] set; }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "RequiresUnsafeAttribute").WithLocation(7, 15),
            // (7,46): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     int P3 { [RequiresUnsafeAttribute] get; [RequiresUnsafeAttribute] set; }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "RequiresUnsafeAttribute").WithLocation(7, 46),
            // (11,31): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     event System.Action E3 { [RequiresUnsafeAttribute] add { } [RequiresUnsafeAttribute] remove { } }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "RequiresUnsafeAttribute").WithLocation(11, 31),
            // (11,65): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     event System.Action E3 { [RequiresUnsafeAttribute] add { } [RequiresUnsafeAttribute] remove { } }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "RequiresUnsafeAttribute").WithLocation(11, 65),
            // (13,6): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     [RequiresUnsafeAttribute] C() { }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "RequiresUnsafeAttribute").WithLocation(13, 6),
            // (16,6): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     [RequiresUnsafeAttribute] public static C operator +(C c1, C c2) => c1;
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "RequiresUnsafeAttribute").WithLocation(16, 6),
            // (17,6): warning CS9368: RequiresUnsafeAttribute is only valid under the updated memory safety rules.
            //     [RequiresUnsafeAttribute] public void operator +=(C c) { }
            Diagnostic(ErrorCode.WRN_RequiresUnsafeAttributeLegacyRules, "RequiresUnsafeAttribute").WithLocation(17, 6),
        };
 
        CreateCompilation(source, [ref1],
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(updatedRules))
            .VerifyDiagnostics(
            [
                .. commonErrors,
                .. (updatedRules ? default(ReadOnlySpan<DiagnosticDescription>) : commonWarnings),
            ]);
 
        var comp2 = CreateCompilation(RequiresUnsafeAttributeDefinition).VerifyDiagnostics();
        var ref2 = AsReference(comp2, useCompilationReference);
 
        CreateCompilation(source, [ref2],
            options: TestOptions.ReleaseDll.WithUpdatedMemorySafetyRules(updatedRules))
            .VerifyDiagnostics(
            [
                .. commonErrors,
                .. (updatedRules ? default(ReadOnlySpan<DiagnosticDescription>) : commonWarnings),
                // (3,12): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                // [assembly: RequiresUnsafeAttribute]
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(3, 12),
                // (2,10): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                // [module: RequiresUnsafeAttribute]
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(2, 10),
                // (2,2): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                // [RequiresUnsafeAttribute] class C
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(2, 2),
                // (25,2): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                // [RequiresUnsafeAttribute] delegate void D();
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(25, 2),
                // (26,2): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                // [RequiresUnsafeAttribute] enum E { X }
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(26, 2),
                // (18,20): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                //     public void M([RequiresUnsafeAttribute] int x) { }
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(18, 20),
                // (20,20): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                //     public void M<[RequiresUnsafeAttribute] T>() { }
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(20, 20),
                // (6,13): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                //     [field: RequiresUnsafeAttribute] int P2 { get; set; }
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(6, 13),
                // (10,13): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                //     [field: RequiresUnsafeAttribute] event System.Action E2;
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(10, 13),
                // (19,14): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                //     [return: RequiresUnsafeAttribute] public int Func() => 0;
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(19, 14),
                // (22,6): error CS0592: Attribute 'RequiresUnsafeAttribute' is not valid on this declaration type. It is only valid on 'constructor, method, property, indexer, event' declarations.
                //     [RequiresUnsafeAttribute] int F;
                Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "RequiresUnsafeAttribute").WithArguments("RequiresUnsafeAttribute", "constructor, method, property, indexer, event").WithLocation(22, 6),
            ]);
    }
}