-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Attribute argument of a type containing function pointer fails with TypeLoadException
during reflection
#80138
Comments
Assigned to @jjonescz for initial investigation (confirm whether this is a runtime/reflection issue). Thanks |
@jcouv Yes, this seems to be runtime issue. The emitted metadata look correct. Here is an IL repro: [Fact]
public void Issue66187()
{
var ilSource = """
.class public auto ansi beforefieldinit A
extends [mscorlib]System.Attribute
{
.method public hidebysig specialname rtspecialname
instance void .ctor (
valuetype B`1/E<method void *()[]> e
) cil managed
{
.maxstack 8
ret
}
}
.class public auto ansi beforefieldinit B`1<T>
extends System.Object
{
.class nested public auto ansi sealed E<T>
extends [mscorlib]System.Enum
{
.param type T
.field public specialname rtspecialname int32 value__
}
}
.class public auto ansi beforefieldinit C
extends System.Object
{
.custom instance void A::.ctor(valuetype B`1/E<method void *()[]>) = (
01 00 00 00 00 00 00 00
)
}
""";
var source = """
using System;
using System.Linq;
var attr = typeof(C).CustomAttributes.Single(d => d.AttributeType == typeof(A));
var arg = attr.ConstructorArguments.Single();
Console.WriteLine((int?)arg.Value == 0);
""";
var comp = CreateCompilationWithIL(source, ilSource).VerifyDiagnostics();
CompileAndVerify(comp, expectedOutput: "True");
} Fails with:
|
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @dotnet/area-system-reflection Issue DetailsVersion Used: 34180c3974c46fe354740d7f5fddd17244474612 (2022-12-20) Discovered while working on dotnet/roslyn#66073. Steps to Reproduce: [Theory, CombinatorialData, WorkItem(65594, "https://github.com/dotnet/roslyn/issues/65594")]
public void Attribute_TypedDefault_Enum([CombinatorialValues("class", "struct")] string kind)
{
var source = $$"""
using System;
using System.Linq;
var attr = typeof(C).CustomAttributes.Single(d => d.AttributeType == typeof(A));
var arg = attr.ConstructorArguments.Single();
Console.WriteLine((int)arg.Value == 0);
class A : Attribute
{
public A(B<delegate*<void>[]>.E e) { }
}
{{kind}} B<T>
{
public enum E { }
}
[A(default)]
class C { }
""";
var verifier = CompileAndVerify(source, expectedOutput: "True", symbolValidator: static module =>
{
var c = module.GlobalNamespace.GetTypeMember("C");
var attr = c.GetAttributes().Single(d => d.AttributeClass?.Name == "A");
Assert.Empty(attr.ConstructorArguments);
});
verifier.VerifyDiagnostics();
} Expected Behavior: The test succeeds. Actual Behavior: At runtime, it fails with:
Changing
|
Function pointers are not currently supported as a reflectable type othan than We are working on adding support in 8.0, although resolving a function pointer from a string may not be supported in 8.0 either as shown in the provided call stack Keeping in 8.0 for re-assessment once the core function pointer work is in. |
This issue still occurs in v8 RC1: namespace ConsoleApp172
{
internal class Program
{
static void Main(string[] args)
{
var attr = typeof(C).CustomAttributes.Single(d => d.AttributeType == typeof(A));
// throws:
var arg = attr.ConstructorArguments.Single();
Console.WriteLine((int)arg.Value == 0);
}
}
class A : Attribute
{
public A(B<delegate*<void>[]>.E e) { }
// This works:
// public A(B<void*[]>.E e) { }
}
class B<T>
{
public enum E { }
}
[A(default)]
class C { }
} Moving to v9 based on priority. |
Closing; this works in latest v9 (Preview 1+). It did not work in v8. I don't have the fix that allowed this to work - previously, the attribute data string could not be properly deserialized: The enum type is based on
The actual benefit from this is very low to none. The original failing test in the PR description is "combinatorial" and I can't think of a useful real-world scenario since:
|
Version Used: dotnet/roslyn@34180c3 (2022-12-20)
Discovered while working on dotnet/roslyn#66073.
Steps to Reproduce:
Expected Behavior: The test succeeds.
Actual Behavior: At runtime, it fails with:
Changing
A
's constructor to take parameter of a different type, e.g.,B<int>.E
instead ofB<delegate*<void>[]>.E
, makes the test pass. (Although I wouldn't expect the symbol validator to discover empty attribute constructor arguments, but that's a different issue - dotnet/roslyn#66370.)The text was updated successfully, but these errors were encountered: