Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P/Invoke extern event has unexpected metadata #76882

Open
jjonescz opened this issue Jan 23, 2025 · 0 comments
Open

P/Invoke extern event has unexpected metadata #76882

jjonescz opened this issue Jan 23, 2025 · 0 comments
Labels
Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead

Comments

@jjonescz
Copy link
Member

Version Used: 347e576

Steps to Reproduce:

Run the following test:

[Fact]
public void ExternEvent()
{
    var source = """
        using System;
        using System.Runtime.InteropServices;
        public static class C
        {
            [method: DllImport("something.dll")]
            public static extern event EventHandler E;
        }
        """;
    CompileAndVerify(source,
        symbolValidator: verify,
        verify: Verification.Skipped)
        .VerifyDiagnostics();

    static void verify(ModuleSymbol module)
    {
        var ev = module.GlobalNamespace.GetMember<EventSymbol>("C.E");
        Assert.True(ev.GetPublicSymbol().IsExtern);
        verifyAccessor(ev.AddMethod!);
        verifyAccessor(ev.RemoveMethod!);
    }

    static void verifyAccessor(MethodSymbol accessor)
    {
        Assert.True(accessor.GetPublicSymbol().IsExtern);

        var importData = accessor.GetDllImportData()!;
        Assert.Equal("something.dll", importData.ModuleName);
        Assert.Equal(accessor.MetadataName, importData.EntryPointName); // 'add_E' or 'remove_E' expected
    }
}

Or simply compile the following program and inspect the IL:

using System;
using System.Runtime.InteropServices;
public static class C
{
    [method: DllImport("something.dll")]
    public static extern event EventHandler E;
}

Expected Behavior: Both add_E and remove_E accessors to be similar.

Actual Behavior: add_E accessor emitted with pinvokeimpl("something.dll" as "remove_E" winapi):

.class public auto ansi abstract sealed beforefieldinit C
	extends [System.Runtime]System.Object
{
	// Methods
	.method public hidebysig specialname static pinvokeimpl("something.dll" as "remove_E" winapi) 
		void add_E (
			class [System.Runtime]System.EventHandler 'value'
		) cil managed preservesig 
	{
		.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
			01 00 00 00
		)
	} // end of method C::add_E

	.method public hidebysig specialname static pinvokeimpl("something.dll" winapi) 
		void remove_E (
			class [System.Runtime]System.EventHandler 'value'
		) cil managed preservesig 
	{
		.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
			01 00 00 00
		)
	} // end of method C::remove_E

	// Events
	.event [System.Runtime]System.EventHandler E
	{
		.addon void C::add_E(class [System.Runtime]System.EventHandler)
		.removeon void C::remove_E(class [System.Runtime]System.EventHandler)
	}
} // end of class C
@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged Issues and PRs which have not yet been triaged by a lead label Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

No branches or pull requests

1 participant