You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
TypeLoadException when a ref struct using explicit layout has fields of type ref struct #111260
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).
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.
@jkotas or @davidwrighton My interpretation of this scenario is that a ByRefLike value type should just be treated as any other value type. The ByRefLike nature of it doesn't impact the overlap or alignment rules.
My plan here would be to remove the alignment check for the ByRefLike type and let the "value type layout" check work for the ByRefLike type "as is". Is there a flaw with that approach?
We need an alignment check on the actual byref fields... If we remove the check on byref like types as a whole, we need to preserve that detail for them.
We need an alignment check on the actual byref fields...
Oh, perhaps you meant that since ref fields only exists on ByRefLike types the this logic was implied. It does seem we validate this now too though. I wrote some of it previously when ref fields were added. I also see this in native AOT.
Activity
jkotas commentedon Jan 10, 2025
The offending imprecise check was introduced in dotnet/coreclr#25200 .
AaronRobinsonMSFT commentedon Jan 19, 2025
@jkotas or @davidwrighton My interpretation of this scenario is that a ByRefLike value type should just be treated as any other value type. The ByRefLike nature of it doesn't impact the overlap or alignment rules.
My plan here would be to remove the alignment check for the ByRefLike type and let the "value type layout" check work for the ByRefLike type "as is". Is there a flaw with that approach?
CoreCLR:
runtime/src/coreclr/vm/methodtablebuilder.cpp
Lines 8680 to 8688 in 29013d8
native AOT:
runtime/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs
Lines 333 to 340 in 29013d8
davidwrighton commentedon Jan 19, 2025
We need an alignment check on the actual byref fields... If we remove the check on byref like types as a whole, we need to preserve that detail for them.
AaronRobinsonMSFT commentedon Jan 19, 2025
Agreed. Does
IsByRefLikereturn true for both ByRefLike types and byref fields?AaronRobinsonMSFT commentedon Jan 19, 2025
Oh, perhaps you meant that since
reffields only exists on ByRefLike types the this logic was implied. It does seem we validate this now too though. I wrote some of it previously whenreffields were added. I also see this in native AOT.AaronRobinsonMSFT commentedon Jan 19, 2025
@davidwrighton It looks like we are missing some check here.
I think I see what you meant by this now. Thanks.