Description
Description
I am currently testing out generating functions on .net 10 preview 5 (windows) and wanted to test out the relatively new feature UnsafeAccessor.
To do this I do the following:
-
Create a type builder
-
Create a public static method that calls the accessor on some struct field that is private
-
Create a nested private extern function that has two custom attributes (CompilerGenerated & Unsafe Accessor) with no il emitted. (Implementation Flags set to IL | PreserveSig). Note: PreserveSig was intentionally placed there after reading through TypeBuilders skipping of method bodies on this flag.
-
Create the type
The function works fine at runtime (because the JIT will replace the IL body) but I notice when I call GetILAsByteArray() it is nonzero. This is a problem for the debugger because it crashes whenever it enters the method (I am assuming it attempts to read the body). Or when writing the function later into a persisted assembly (this isnt as big of a problem because I can make a filter for UnsafeAccessors).
The IL it seemed to copy from appears to be method 1.
Reproduction Steps
-
Create a type builder
-
Create a public static method that calls the accessor on some struct field that is private
-
Create a nested private extern function that has two custom attributes (CompilerGenerated & Unsafe Accessor) with no il emitted. (Implementation Flags set to IL | PreserveSig)
-
Create the type
Expected behavior
public struct Val6 : Base.Val<Base.Int>, IJulia
{
[SpecialName]
public static Base.Int get_Value()
{
Base.Int @int;
Val6.field(ref @int) = new IntPtr(4);
return @int;
}
[CompilerGenerated]
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<Value>k__BackingField")]
internal static extern ref IntPtr field(ref Base.Int _param0);
}
Actual behavior
public struct Val6 : Base.Val<Base.Int>, IJulia
{
[SpecialName]
public static Base.Int get_Value()
{
Base.Int @int;
Val6.field(ref @int) = new IntPtr(4);
return @int;
}
[CompilerGenerated]
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<Value>k__BackingField")]
[MethodImpl(MethodImplOptions.PreserveSig)]
internal static ref IntPtr field(ref Base.Int _param0)
{
Base.Int @int;
Val6.field(ref @int) = new IntPtr(4); //Stack overflow here for debugger.
// ISSUE: cast to a reference type
return (IntPtr&) @int;
}
}
Note in the above that nothing was emitted into 'fields' il ... it copied it over somehow from get_Value.
Regression?
No response
Known Workarounds
No response
Configuration
.net 10 preview 5 (windows) x86_64; Release; Debug; Tier0; Tier1
Other information
Stepping through System.Private.CoreLIB's TypeBuilder.CreateTypeNoLock() this function should be skipping setting any IL because of the PreserveSig flag (continue to the next method when ImplFlag & PreserveSig != 0)
Not sure where this extra IL is getting added.... I dont think it is before the type creation though.