-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
When building a dynamic assembly via reflection with the various *Builder classes, non-public attributes are explicitly ignored in mono.
In mono_custom_attrs_from_builders_handle:
runtime/src/mono/mono/metadata/custom-attrs.c
Lines 738 to 741 in 6122bba
| for (int i = 0; i < count; ++i) { | |
| MONO_HANDLE_ARRAY_GETREF (cattr, cattrs, i); | |
| if (!custom_attr_visible (image, cattr, ctor_handle, &ctor_method)) | |
| continue; |
There's a comment about it matching .NET, but that is not what I see with coreclr or .NET Framework.
runtime/src/mono/mono/metadata/custom-attrs.c
Line 723 in 6122bba
| /* Skip nonpublic attributes since MS.NET seems to do the same */ |
Not sure if there's another reason mono skips non-public attributes?
Reproduction Steps
Dynamic assembly with an assembly-level non-public attribute:
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule");
// Create internal attribute
TypeBuilder typeBuilder = moduleBuilder.DefineType("InternalAttribute", TypeAttributes.NotPublic, typeof(Attribute));
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[0]);
constructorBuilder.GetILGenerator().Emit(OpCodes.Ret);
// Add assembly-level attribute
ConstructorInfo constructorInfo = typeBuilder.CreateTypeInfo().GetConstructor(Array.Empty<Type>());
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(constructorInfo, Array.Empty<object>());
assemblyBuilder.SetCustomAttribute(customAttributeBuilder);
IList<CustomAttributeData> attrs = assemblyBuilder.GetCustomAttributesData();
Console.WriteLine($"{assemblyBuilder.GetName().Name} - Attributes (count: {attrs.Count})");
foreach (CustomAttributeData attr in attrs)
{
Console.WriteLine($" {attr}");
}Expected behavior
The internal attribute is listed. On coreclr (and also .NET Framework 4.6.2), the above prints:
DynamicAssembly - Attributes (count: 1)
[InternalAttribute()]
Actual behavior
The internal attribute is not listed. On mono, the above prints:
DynamicAssembly - Attributes (count: 0)
Other information
This results in the test infrastructure for Roslyn analyzers (in dotnet/roslyn-sdk) being unable to run on mono.
They rely on emitting a non-public IgnoresAccessChecksToAttribute to skip access checks. Since mono ends up ignoring the attribute, using their test infrastructure results in:
System.MethodAccessException : Method `Microsoft.CodeAnalysis.Testing.AnalyzerInfo+CustomAnalysisContext..ctor()' is inaccessible from method `CustomAnalysisContextImpl..ctor()'
Stack Trace:
at CustomAnalysisContextImpl..ctor()
cc @lambdageek