Skip to content

DefineUninitializedData on TypeBuilder in System.Reflection.Emit uses typeof(ValueType) internally even when using a MetadataLoadContext #105772

@TrueLunacy

Description

@TrueLunacy

Description

DefineUninitializedData on TypeBuilder in System.Reflection.Emit uses typeof(ValueType) internally, even when using a MetadataLoadContext.

This causes type.IsValueType to return false even though it is true, which causes invalid IL to be emitted (fields are being marked class when they should be marked valuetype, causing failures to load)

Reproduction Steps

using System.Reflection;
using System.Reflection.Emit;

var pathres = new PathAssemblyResolver([typeof(object).Assembly.Location]);
var mlc = new MetadataLoadContext(pathres, typeof(object).Assembly.GetName().Name);

PersistedAssemblyBuilder pab = new PersistedAssemblyBuilder(
    new AssemblyName("MyAssembly"),
    mlc.CoreAssembly!
);

ModuleBuilder mb = pab.DefineDynamicModule("Module");
TypeBuilder tb = mb.DefineType("Type");

var field = tb.DefineUninitializedData("UninitializedDataField", 100, FieldAttributes.Public);
var type = field.FieldType.BaseType;

Console.WriteLine(type.IsValueType);
Console.WriteLine(type);
Console.WriteLine(type == typeof(ValueType));

var contextValueType = mlc.CoreAssembly!.GetType("ValueType")!;
Console.WriteLine(type == contextValueType);
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.Reflection.MetadataLoadContext" Version="8.0.0" />
  </ItemGroup>

</Project>

Expected behavior

type.IsValueType should return true.
type == typeof(ValueType) should return false.
type == contextValueType should return true.

Actual behavior

type.IsValueType returns false.
type == typeof(ValueType) returns true.
type == contextValueType returns false.

Regression?

Unknown

Known Workarounds

No response

Configuration

Arch Linux x64, dotnet 9.0.100-rc.1.24381.3

Other information

As far as I can tell, this appears to be because DefineDataHelper in TypeBuilderImpl.cs uses typeof(ValueType) to define its helper type.

Metadata

Metadata

Assignees

Labels

area-System.Reflectionin-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions