Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@ static class DiagnosticUtilities
internal static string GetParameterNameForErrorMessage(ParameterDefinition parameterDefinition) =>
string.IsNullOrEmpty(parameterDefinition.Name) ? $"#{parameterDefinition.Index}" : parameterDefinition.Name;

internal static string GetGenericParameterDeclaringMemberDisplayName(GenericParameter genericParameter) =>
genericParameter.DeclaringMethod != null ?
genericParameter.DeclaringMethod.GetDisplayName() :
genericParameter.DeclaringType.GetDisplayName();
internal static string GetGenericParameterDeclaringMemberDisplayName(GenericParameter genericParameter)
{
if (genericParameter.DeclaringMethod is MethodReference declaringMethod)
return declaringMethod.Name;

if (genericParameter.DeclaringType is TypeReference declaringType)
return declaringType.Name;

return genericParameter.Name;
}

internal static string GetMethodSignatureDisplayName(IMethodSignature methodSignature) =>
(methodSignature is MethodReference method) ? method.GetDisplayName() : (methodSignature.ToString() ?? string.Empty);
Expand Down
3 changes: 3 additions & 0 deletions src/tools/illink/src/linker/Linker.Steps/MarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,9 @@ protected internal virtual void MarkCustomAttribute(CustomAttribute ca, in Depen
MarkCustomAttributeArguments(ca, origin);

TypeReference constructor_type = ca.Constructor.DeclaringType;
if (GenericArgumentDataFlow.RequiresGenericArgumentDataFlow(Context.Annotations.FlowAnnotations, constructor_type))
GenericArgumentDataFlow.ProcessGenericArgumentDataFlow(in origin, this, Context, constructor_type);

Comment on lines 1190 to +1193
TypeDefinition? type = Context.Resolve(constructor_type);

if (type == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ public static string GetDisplayName(this MemberReference member)

public static string GetNamespaceDisplayName(this MemberReference member)
{
if (member == null)
return string.Empty;

var type = member is TypeReference typeReference ? typeReference : member.DeclaringType;
if (type == null)
return string.Empty;

while (type.DeclaringType != null)
type = type.DeclaringType;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.assembly extern System.Runtime
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )
}
.assembly 'GenericAttributesDataFlow'
{
.hash algorithm 0x00008004
.ver 1:0:0:0
}
.module GenericAttributesDataFlow.dll

.namespace Mono.Linker.Tests.Cases.Attributes.Dependencies
{
.class public auto ansi beforefieldinit DynamicallyAccessedMembersGenericAttribute`1<T>
extends [System.Runtime]System.Attribute
{
.param type T
.custom instance void [System.Runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute::.ctor(valuetype [System.Runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes) = (
01 00 08 00 00 00 00 00
)

.method public hidebysig specialname rtspecialname
instance default void '.ctor' () cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void class [System.Runtime]System.Attribute::'.ctor'()
IL_0006: ret
}
}

.class public auto ansi beforefieldinit DynamicallyAccessedMembersGenericClass`1<T>
extends [System.Runtime]System.Object
{
.custom instance void class Mono.Linker.Tests.Cases.Attributes.Dependencies.DynamicallyAccessedMembersGenericAttribute`1<!T>::'.ctor'() = (01 00 00 00)

.method public hidebysig specialname rtspecialname
instance default void '.ctor' () cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void class [System.Runtime]System.Object::'.ctor'()
IL_0006: ret
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;

namespace Mono.Linker.Tests.Cases.Attributes
{
[SetupCompileBefore("GenericAttributesDataFlow.dll", new[] { "Dependencies/GenericAttributesDataFlow.il" })]
class GenericAttributes
{
static void Main()
{
new WithGenericAttribute_OfString();
new WithGenericAttribute_OfInt();
new WithConstrainedGenericAttribute();
typeof(WithNewConstrainedGenericAttribute).GetCustomAttributes(false);
ReflectOnGenericAttributeWithUnannotatedTypeParameter<TypeWithPublicMethods>.Test();
ReflectOnGenericAttributeWithAnnotatedTypeParameter<TypeWithPublicMethods>.Test();
}

[Kept]
Expand Down Expand Up @@ -60,6 +67,13 @@ class ConstraintType
{
}

[Kept]
class TypeWithPublicMethods
{
[Kept]
public void Method() { }
}

[KeptBaseType(typeof(ConstraintType))]
class DerivedFromConstraintType : ConstraintType
{
Expand All @@ -72,5 +86,60 @@ class ConstrainedGenericAttribute<T> : Attribute
[Kept]
public ConstrainedGenericAttribute() { }
}

[Kept]
class Handler
{
[Kept]
public Handler() { }
}

[Kept]
[KeptAttributeAttribute(typeof(NewConstrainedGenericAttribute<Handler>))]
[KeptMember(".ctor()")]
[NewConstrainedGenericAttribute<Handler>]
class WithNewConstrainedGenericAttribute
{
}

[Kept]
[KeptBaseType(typeof(Attribute))]
class NewConstrainedGenericAttribute<[KeptGenericParamAttributes(GenericParameterAttributes.DefaultConstructorConstraint)] T> : Attribute
where T : new()
{
[Kept]
public NewConstrainedGenericAttribute() { }
}

[Kept]
class ReflectOnGenericAttributeWithUnannotatedTypeParameter<T>
{
[Kept]
[ExpectedWarning("IL2091", Tool.Trimmer | Tool.NativeAot, "")]
public static void Test()
{
GetDynamicallyAccessedMembersGenericClass(typeof(T)).GetCustomAttributes(false);
}
}

[Kept]
class ReflectOnGenericAttributeWithAnnotatedTypeParameter<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
[KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))]
T>()
{
[Kept]
public static void Test()
{
GetDynamicallyAccessedMembersGenericClass(typeof(T)).GetCustomAttributes(false);
}
}

[Kept]
static Type GetDynamicallyAccessedMembersGenericClass(Type typeArgument)
{
return Type.GetType("Mono.Linker.Tests.Cases.Attributes.Dependencies.DynamicallyAccessedMembersGenericClass`1, GenericAttributesDataFlow")!
.MakeGenericType(typeArgument);
}
}
}
Loading