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

TypeLoadException when a ref struct using explicit layout has fields of type ref struct #111260

Open
lithiumtoast opened this issue Jan 10, 2025 · 1 comment
Labels
area-TypeSystem-coreclr untriaged New issue has not been triaged by the area owner

Comments

@lithiumtoast
Copy link

lithiumtoast commented Jan 10, 2025

Description

Context: Found in .NET 9 when experimenting with ref struct in P/Invoke scenarios. I want to make it clear that I'm not using "ref fields" but rather only "ref structs"; the fields of the struct are not ref (pointer) but the type is of ref struct (stack-only).

Reproduction Steps

using System;
using System.Runtime.InteropServices;
					
public class Program
{
    [StructLayout(LayoutKind.Explicit, Size = 8, Pack = 8)]
    public ref struct Foo
    {
        [FieldOffset(0)]
        public Bar A;
        [FieldOffset(4)]
        public Bar B;
    }

    public ref struct Bar
    {
        public uint Value;
    }
	
    public static void Main()
    {
	var e = default(Foo);
	e.A.Value = 1;
	e.B.Value = 2;
	Console.WriteLine("1 + 2 = " + (e.A.Value + e.B.Value));
    }
}

Expected behavior

A ref struct of explicit layout can have fields that are positioned using FieldOffset attribute where the type of the field is a ref struct without creating a runtime exception.

Actual behavior

When a ref struct is using explicit struct layout, a System.TypeLoadException can occur regarding the field offset of the struct's field which the type is another ref struct.

Unhandled exception. System.TypeLoadException: Could not load type 'Foo' from assembly 'r2oeekw4.exe, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 4 that is incorrectly aligned or overlapped by a non-object field.
   at Program.Main()

Regression?

No response

Known Workarounds

  • Removing the ref from the nested struct.

Configuration

  • .NET 9
  • macOS Ventura 13.6.5
  • Apple M1 (osx-arm64)
  • Not specific to any configuration.

Other information

Hypothesis: The word ref in the context of a struct (stack-only) is confused to be in the context of a field (pointer); the field is mistaken for an object type with rules about field alignment when it's actually a struct.

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Jan 10, 2025
@jkotas
Copy link
Member

jkotas commented Jan 10, 2025

The offending imprecise check was introduced in dotnet/coreclr#25200 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-TypeSystem-coreclr untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

2 participants