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

UnmanagedCallersOnly functions with bool/char parameters should be an error #64086

Closed
rolfbjarne opened this issue Sep 16, 2022 · 8 comments
Closed
Labels
Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead

Comments

@rolfbjarne
Copy link
Member

rolfbjarne commented Sep 16, 2022

Version Used:

Steps to Reproduce:

See:

Code:

using System.Runtime.InteropServices;

class App
{
    public unsafe static void Main ()
    {
        delegate* unmanaged<bool, void> i = &I;
        i(true);
    }

    [UnmanagedCallersOnly]
    static void I (bool fileRegion)
    {
    }
}

Note: char has the exact same problem.

Expected Behavior:

A compiler error:

Program.cs(12,20): error CS8894: Cannot use 'bool' as a parameter type on a method attributed with 'UnmanagedCallersOnly'.

Actual Behavior:

Compilation succeeds, but an exception is thrown at runtime:

Unhandled exception. System.InvalidProgramException: Non-blittable parameter types are invalid for UnmanagedCallersOnly methods.
   at App.Main() in /Users/rolf/test/dotnet/console2/Program.cs:line 8

This bug is very similar to #57025, where the same problem occurred, except with ref parameters instead of bool / char parameters.

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Sep 16, 2022
@rolfbjarne rolfbjarne changed the title UnmanagedCallersOnly functions with bool parameters should be an error UnmanagedCallersOnly functions with bool/char parameters should be an error Sep 16, 2022
@tannergooding
Copy link
Member

This is a case where the exact behavior of bool/char is runtime/scenario dependent.

For RyuJIT, this should work with the new DisableRuntimeMarshallingAttribute.

CC. @jkotas, @AaronRobinsonMSFT

@rolfbjarne
Copy link
Member Author

@tannergooding does [DisableRuntimeMarshalling] make ref parameters blittable too (#57025)?

@jkotas
Copy link
Member

jkotas commented Sep 16, 2022

It is no different from other invalid combinations of types or interop marshalling attributes on e.g. DllImport. They are only caught at runtime. Roslyn does not flag them as errors. It is intentional design.

@tannergooding does [DisableRuntimeMarshalling] make ref parameters blittable too (#57025)?

No. ref is never blittable and requires marshalling.

rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this issue Sep 16, 2022
'bool' isn't a blittable type, so it can't be used in an
[UnmanagedCallersOnly] method.

FWIW it's a bug in the C# compiler to not complain about this:
dotnet/roslyn#64086.

Fixes this crash in the AOT compiler:

> * Assertion at /Users/runner/work/1/s/src/mono/mono/mini/aot-compiler.c:5142, condition `is_ok (error)' not met, function:add_wrappers, method CoreMedia.CMBufferQueue:GetDataReady (intptr,intptr) with UnmanagedCallersOnlyAttribute has non-blittable parameters or return type assembly:<unknown assembly> type:<unknown type> member:(null)

Also exclude some unused delegates from .NET code.
rolfbjarne added a commit to xamarin/xamarin-macios that referenced this issue Sep 19, 2022
…5986)

'bool' isn't a blittable type, so it can't be used in an
[UnmanagedCallersOnly] method.

FWIW it's a bug in the C# compiler to not complain about this:
dotnet/roslyn#64086.

Fixes this crash in the AOT compiler:

> * Assertion at /Users/runner/work/1/s/src/mono/mono/mini/aot-compiler.c:5142, condition `is_ok (error)' not met, function:add_wrappers, method CoreMedia.CMBufferQueue:GetDataReady (intptr,intptr) with UnmanagedCallersOnlyAttribute has non-blittable parameters or return type assembly:<unknown assembly> type:<unknown type> member:(null)

Also exclude some unused delegates from .NET code.
@jaredpar
Copy link
Member

Disallowing bool / char in a method, even [UnmanagedCallersOnly], seems like a pretty significant break for the compiler. Is there a justification big enough to warrant such a break? Not really seeing it in this thread.

@jaredpar jaredpar added Need More Info The issue needs more information to proceed. and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Oct 11, 2022
@rolfbjarne
Copy link
Member Author

Disallowing bool / char in a method, even [UnmanagedCallersOnly], seems like a pretty significant break for the compiler. Is there a justification big enough to warrant such a break? Not really seeing it in this thread.

This issue is very similar to #57025, where you said the break was acceptable: #57025 (comment)

The only difference I see is that this case is scenario dependent, since the [DisableRuntimeMarshallingAttribute] can change marshalling behavior to make the test case work - but I believe the compiler has enough information to determine if this is the case (does the assembly have the attribute or not?) and not issue an error. Another point here is that [DisableRuntimeMarshallingAttribute] has not been released yet, which means that all existing P/Invokes with such signatures are broken.

My personal take is that the compiler does not allow any other non-blittable types in the signature of a [UnmanagedCallersOnly] method, which leads me to believe that if the compiler doesn't complain about a signature, the signature is OK.

Another point is that not many people know exactly which types are blittable or not, so this is a very easy mistake to make (I didn't know, and I've written quite a few P/Invokes over the years, and neither did you guys when you implemented support for [UnmanagedCallersOnly] in csc, otherwise you'd made csc show an error for both #57025 and this issue from the very beginning).

@ghost ghost added untriaged Issues and PRs which have not yet been triaged by a lead and removed Need More Info The issue needs more information to proceed. labels Oct 11, 2022
@jaredpar
Copy link
Member

This issue is very similar to #57025, where you said the break was acceptable: #57025 (comment)

These are very different. The number of methods that have ref parameters are far smaller than ones that have bool / char.

I believe the compiler has enough information to determine if this is the case (does the assembly have the attribute or not?

The compiler does not process this attribute and has no behavior associated with it.

Closing this as there does not seem to be concensus from runtime team that this should be an error. Will reconsider if that conseus happens.

@tannergooding
Copy link
Member

Just noting I think the behavior is fine "as is" today. Users can make it work and it will trivially fail at runtime if the code gets used.

The runtime could potentially improve the exception message to call out DisableRuntimeMarshallingAttribute as a possible fix if desired (CC. @jkoritzinsky)

@AaronRobinsonMSFT
Copy link
Member

The runtime could potentially improve the exception message to call out DisableRuntimeMarshallingAttribute as a possible fix if desired (CC. @jkoritzinsky)

This does make sense.

@rolfbjarne Would updating the error message be a reasonable compromise?

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

5 participants