Skip to content

Dereferencing a pointer to a byte-sized structure reads a DWORD  #68157

@AndrejStanisev

Description

@AndrejStanisev

Description

We have a structure containing one byte, as follows:

struct Byte
{
    private readonly byte Value;
}

Both sizeof and Marshal.SizeOf return 1 for this structure, as expected.

However, dereferencing a pointer (or a ref) to this structure causes JIT to emit a MOV DWORD, rather than MOV BYTE.

We have a real-world case where the pointer points to a chunk of unmanaged memory, and this results in a read past the boundary of allocated memory.

Substituting the structure for a byte produces a MOV BYTE.

Reproduction Steps

Given this:

struct Byte
{
    private readonly byte Value;
}

class Test
{
    [MethodImpl(MethodImplOptions.NoInlining)]
    public static unsafe Byte* GetStructPtr() => null; //Implementation of the method is irrelevant
    public static unsafe Byte GetStructValue() => *GetStructPtr();
}

Test.GetStructValue();

The JIT produces this:

public static unsafe Byte GetStructValue() => *GetStructPtr();
00007FFA96CF8EC0  push        rbp  
00007FFA96CF8EC1  sub         rsp,20h  
00007FFA96CF8EC5  lea         rbp,[rsp+20h]  
00007FFA96CF8ECA  call        Method stub for: Test.GetStructPtr() (07FFA96CF8390h)  
00007FFA96CF8ECF  mov         eax,dword ptr [rax]  

Expected behavior

The JIT should emit code to read a single byte.

Actual behavior

The JIT emits code reading a DWORD.

Regression?

No response

Known Workarounds

Substitute the structure for a byte.

Configuration

.NET 6
Windows
x64

Other information

No response

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions