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

Roslyn codegen impacting array variance exception behavior #73215

Open
stephentoub opened this issue Apr 24, 2024 · 5 comments
Open

Roslyn codegen impacting array variance exception behavior #73215

stephentoub opened this issue Apr 24, 2024 · 5 comments

Comments

@stephentoub
Copy link
Member

stephentoub commented Apr 24, 2024

This code throws an ArrayTypeMismatchException:

Set(new Program[1]);

static void Set(object[] array)
{
    ref var o = ref array[0];
    Use(ref o);

    static void Use(ref object o) { }
}

SharpLab

; Method Program:<<Main>$>g__Set|0_0(System.Object[]) (FullOpts)
G_M000_IG01:                ;; offset=0x0000
       sub      rsp, 40

G_M000_IG02:                ;; offset=0x0004
       xor      edx, edx
       mov      r8, 0x7FFA8E1A5FA8
       call     CORINFO_HELP_LDELEMA_REF
       nop      

G_M000_IG03:                ;; offset=0x0016
       add      rsp, 40
       ret      
; Total bytes of code: 27

But this code does not:

Set(new Program[1]);

static void Set(object[] array)
{
    ref var o = ref array[0];
}

SharpLab

; Method Program:<<Main>$>g__Set|0_0(System.Object[]) (FullOpts)
G_M000_IG01:                ;; offset=0x0000
       sub      rsp, 40

G_M000_IG02:                ;; offset=0x0004
       cmp      dword ptr [rcx+0x08], 0
       jbe      SHORT G_M000_IG04

G_M000_IG03:                ;; offset=0x000A
       add      rsp, 40
       ret      

G_M000_IG04:                ;; offset=0x000F
       call     CORINFO_HELP_RNGCHKFAIL
       int3     
; Total bytes of code: 21

By eliding the CORINFO_HELP_LDELEMA_REF call that does the variance checking, does that mean the JIT's optimizations are changing program behavior in a way we try not to?

@dotnet-policy-service dotnet-policy-service bot added the untriaged Issues and PRs which have not yet been triaged by a lead label Apr 24, 2024
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

@SingleAccretion
Copy link

SingleAccretion commented Apr 24, 2024

This is due to a difference in IL generated by Roslyn.

static void Set(object[] array)
{
    ref var o = ref array[0];
}

Uses ldelem instead of ldelema:

IL to import:
IL_0000  03                ldarg.1
IL_0001  16                ldc.i4.0
IL_0002  9a                ldelem.ref
IL_0003  26                pop
IL_0004  2a                ret

@EgorBo
Copy link
Member

EgorBo commented Apr 24, 2024

And Roslyn uses ldelema for the same C# snippet compiled in Debug

@stephentoub
Copy link
Member Author

stephentoub commented Apr 24, 2024

I hadn't noticed that IL difference. I assume that means we'd consider this a Roslyn bug and it should always be using ldelema?

@SingleAccretion
Copy link

Depending on what the C# specification says, yes. It's not a runtime bug in any case.

@stephentoub stephentoub changed the title JIT performing an optimization around array variance that's changing behavior? Roslyn codegen impacting array variance exception behavior Apr 24, 2024
@stephentoub stephentoub transferred this issue from dotnet/runtime Apr 24, 2024
@jaredpar jaredpar added Bug New Language Feature - Ref Locals and Returns Ref Locals and Returns and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Apr 25, 2024
@jaredpar jaredpar added this to the 17.11 milestone Apr 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants