diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs index a18251e401fc03..a83ad7506418b8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs @@ -10,6 +10,9 @@ using Internal.TypeSystem.Ecma; using DependencyList = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore.DependencyList; +using DependencyListEntry = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore.DependencyListEntry; +using CombinedDependencyList = System.Collections.Generic.List.CombinedDependencyListEntry>; +using CombinedDependencyListEntry = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore.CombinedDependencyListEntry; using MethodAttributes = System.Reflection.MethodAttributes; namespace ILCompiler.DependencyAnalysis @@ -20,27 +23,35 @@ namespace ILCompiler.DependencyAnalysis /// internal static class CustomAttributeBasedDependencyAlgorithm { - public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaMethod method) + private static IMethodNode GetMetadataApiDependency(NodeFactory factory, string entityName, string propertyName) + => factory.MethodEntrypoint(factory.TypeSystemContext.SystemModule.GetType("Internal.Metadata.NativeFormat", entityName).GetMethod(propertyName, null)); + + private static IMethodNode GetMetadataApiDependency(NodeFactory factory, string entityName) + => GetMetadataApiDependency(factory, entityName, "get_CustomAttributes"); + + public static void AddDependenciesDueToCustomAttributes(ref CombinedDependencyList dependencies, NodeFactory factory, EcmaMethod method) { MetadataReader reader = method.MetadataReader; MethodDefinitionHandle methodHandle = method.Handle; MethodDefinition methodDef = reader.GetMethodDefinition(methodHandle); // Handle custom attributes on the method - AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, methodDef.GetCustomAttributes(), method); + AddDependenciesDueToCustomAttributes(ref dependencies, GetMetadataApiDependency(factory, "Method"), factory, method.Module, methodDef.GetCustomAttributes(), method); // Handle custom attributes on method parameters + object parameterCondition = GetMetadataApiDependency(factory, "Parameter"); foreach (ParameterHandle parameterHandle in methodDef.GetParameters()) { Parameter parameter = reader.GetParameter(parameterHandle); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes(), method); + AddDependenciesDueToCustomAttributes(ref dependencies, parameterCondition, factory, method.Module, parameter.GetCustomAttributes(), method); } // Handle custom attributes on generic method parameters + object genericParameterCondition = GetMetadataApiDependency(factory, "GenericParameter"); foreach (GenericParameterHandle genericParameterHandle in methodDef.GetGenericParameters()) { GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes(), method); + AddDependenciesDueToCustomAttributes(ref dependencies, genericParameterCondition, factory, method.Module, parameter.GetCustomAttributes(), method); } // We don't model properties and events as separate entities within the compiler, so ensuring @@ -50,6 +61,7 @@ public static void AddDependenciesDueToCustomAttributes(ref DependencyList depen // As a performance optimization, we look for associated events and properties only // if the method is SpecialName. This is required for CLS compliance and compilers we // care about emit accessors like this. + object propertyCondition = GetMetadataApiDependency(factory, "Property"); if ((methodDef.Attributes & MethodAttributes.SpecialName) != 0) { TypeDefinition declaringType = reader.GetTypeDefinition(methodDef.GetDeclaringType()); @@ -60,50 +72,52 @@ public static void AddDependenciesDueToCustomAttributes(ref DependencyList depen PropertyAccessors accessors = property.GetAccessors(); if (accessors.Getter == methodHandle || accessors.Setter == methodHandle) - AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, property.GetCustomAttributes(), new PropertyPseudoDesc((EcmaType)method.OwningType, propertyHandle)); + AddDependenciesDueToCustomAttributes(ref dependencies, propertyCondition, factory, method.Module, property.GetCustomAttributes(), new PropertyPseudoDesc((EcmaType)method.OwningType, propertyHandle)); } + object eventCondition = GetMetadataApiDependency(factory, "Event"); foreach (EventDefinitionHandle eventHandle in declaringType.GetEvents()) { EventDefinition @event = reader.GetEventDefinition(eventHandle); EventAccessors accessors = @event.GetAccessors(); if (accessors.Adder == methodHandle || accessors.Remover == methodHandle || accessors.Raiser == methodHandle) - AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, @event.GetCustomAttributes(), new EventPseudoDesc((EcmaType)method.OwningType, eventHandle)); + AddDependenciesDueToCustomAttributes(ref dependencies, eventCondition, factory, method.Module, @event.GetCustomAttributes(), new EventPseudoDesc((EcmaType)method.OwningType, eventHandle)); } } } - public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaType type) + public static void AddDependenciesDueToCustomAttributes(ref CombinedDependencyList dependencies, NodeFactory factory, EcmaType type) { MetadataReader reader = type.MetadataReader; TypeDefinition typeDef = reader.GetTypeDefinition(type.Handle); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, typeDef.GetCustomAttributes(), type); + AddDependenciesDueToCustomAttributes(ref dependencies, GetMetadataApiDependency(factory, "TypeDefinition"), factory, type.EcmaModule, typeDef.GetCustomAttributes(), type); // Handle custom attributes on generic type parameters + object genericParameterCondition = GetMetadataApiDependency(factory, "GenericParameter"); foreach (GenericParameterHandle genericParameterHandle in typeDef.GetGenericParameters()) { GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, parameter.GetCustomAttributes(), type); + AddDependenciesDueToCustomAttributes(ref dependencies, genericParameterCondition, factory, type.EcmaModule, parameter.GetCustomAttributes(), type); } } - public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaField field) + public static void AddDependenciesDueToCustomAttributes(ref CombinedDependencyList dependencies, NodeFactory factory, EcmaField field) { FieldDefinition fieldDef = field.MetadataReader.GetFieldDefinition(field.Handle); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, field.Module, fieldDef.GetCustomAttributes(), field); + AddDependenciesDueToCustomAttributes(ref dependencies, GetMetadataApiDependency(factory, "Field"), factory, field.Module, fieldDef.GetCustomAttributes(), field); } - public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaAssembly assembly) + public static void AddDependenciesDueToCustomAttributes(ref CombinedDependencyList dependencies, NodeFactory factory, EcmaAssembly assembly) { AssemblyDefinition asmDef = assembly.MetadataReader.GetAssemblyDefinition(); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, asmDef.GetCustomAttributes(), assembly); + AddDependenciesDueToCustomAttributes(ref dependencies, GetMetadataApiDependency(factory, "ScopeDefinition"), factory, assembly, asmDef.GetCustomAttributes(), assembly); ModuleDefinition moduleDef = assembly.MetadataReader.GetModuleDefinition(); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, moduleDef.GetCustomAttributes(), assembly); + AddDependenciesDueToCustomAttributes(ref dependencies, GetMetadataApiDependency(factory, "ScopeDefinition", "get_ModuleCustomAttributes"), factory, assembly, moduleDef.GetCustomAttributes(), assembly); } - private static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaModule module, CustomAttributeHandleCollection attributeHandles, TypeSystemEntity parent) + private static void AddDependenciesDueToCustomAttributes(ref CombinedDependencyList dependencies, object condition, NodeFactory factory, EcmaModule module, CustomAttributeHandleCollection attributeHandles, TypeSystemEntity parent) { MetadataReader reader = module.MetadataReader; var mdManager = (UsageBasedMetadataManager)factory.MetadataManager; @@ -134,9 +148,14 @@ private static void AddDependenciesDueToCustomAttributes(ref DependencyList depe if (AddDependenciesFromCustomAttributeBlob(caDependencies, factory, constructor.OwningType, decodedValue)) { - dependencies ??= new DependencyList(); - dependencies.AddRange(caDependencies); - dependencies.Add(factory.CustomAttributeMetadata(new ReflectableCustomAttribute(module, caHandle)), "Attribute metadata"); + dependencies ??= new CombinedDependencyList(); + + foreach (DependencyListEntry caDependency in caDependencies) + { + dependencies.Add(new CombinedDependencyListEntry(caDependency.Node, condition, caDependency.Reason)); + } + + dependencies.Add(new CombinedDependencyListEntry(factory.CustomAttributeMetadata(new ReflectableCustomAttribute(module, caHandle)), condition, "Attribute metadata")); } } catch (TypeSystemException) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs index 77fa28233c8268..68837a34384644 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs @@ -40,8 +40,6 @@ public override IEnumerable GetStaticDependencies(NodeFacto DependencyList dependencies = new DependencyList(); dependencies.Add(factory.TypeMetadata((MetadataType)_field.OwningType), "Owning type metadata"); - CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ((EcmaField)_field)); - if (_field is EcmaField ecmaField) { DynamicDependencyAttributesOnEntityNode.AddDependenciesDueToDynamicDependencyAttribute(ref dependencies, factory, ecmaField); @@ -62,6 +60,14 @@ public override IEnumerable GetStaticDependencies(NodeFacto return dependencies; } + + public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) + { + var dependencies = new List(); + CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, (EcmaField)_field); + return dependencies; + } + protected override string GetName(NodeFactory factory) { return "Field metadata: " + _field.ToString(); @@ -75,9 +81,8 @@ protected override void OnMarked(NodeFactory factory) public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; - public override bool HasConditionalStaticDependencies => false; + public override bool HasConditionalStaticDependencies => true; public override bool StaticDependenciesAreComputed => true; - public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs index 8eaade82cc95f3..8cccdf4b93ea93 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs @@ -44,8 +44,6 @@ public override IEnumerable GetStaticDependencies(NodeFacto if (!_isMinimal) { - CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, _method); - foreach (var parameterHandle in _method.MetadataReader.GetMethodDefinition(_method.Handle).GetParameters()) { dependencies.Add(factory.MethodParameterMetadata(new ReflectableParameter(_method.Module, parameterHandle)), "Parameter is visible"); @@ -83,6 +81,14 @@ public override IEnumerable GetStaticDependencies(NodeFacto return dependencies; } + + public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) + { + var dependencies = new List(); + CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, _method); + return dependencies; + } + protected override string GetName(NodeFactory factory) { return "Method metadata: " + _method.ToString(); @@ -96,9 +102,8 @@ protected override void OnMarked(NodeFactory factory) public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; - public override bool HasConditionalStaticDependencies => false; + public override bool HasConditionalStaticDependencies => !_isMinimal; public override bool StaticDependenciesAreComputed => true; - public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ModuleMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ModuleMetadataNode.cs index ef1e8e9ab5b1ec..f913ca95197e8c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ModuleMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ModuleMetadataNode.cs @@ -46,8 +46,6 @@ public override IEnumerable GetStaticDependencies(NodeFacto EcmaAssembly ecmaAssembly = (EcmaAssembly)_module; - CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ecmaAssembly); - foreach (EcmaModule satelliteModule in ((UsageBasedMetadataManager)factory.MetadataManager).GetSatelliteAssemblies(ecmaAssembly)) { dependencies.Add(factory.ModuleMetadata(satelliteModule), "Satellite assembly"); @@ -56,6 +54,13 @@ public override IEnumerable GetStaticDependencies(NodeFacto return dependencies; } + public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) + { + var dependencies = new List(); + CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, (EcmaAssembly)_module); + return dependencies; + } + protected override string GetName(NodeFactory factory) { return "Reflectable module: " + ((IAssemblyDesc)_module).GetName().FullName; @@ -63,9 +68,8 @@ protected override string GetName(NodeFactory factory) public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; - public override bool HasConditionalStaticDependencies => false; + public override bool HasConditionalStaticDependencies => true; public override bool StaticDependenciesAreComputed => true; - public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs index 32c826adf5f21f..0d26a15756011c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs @@ -37,8 +37,6 @@ public override IEnumerable GetStaticDependencies(NodeFacto { DependencyList dependencies = new DependencyList(); - CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ((EcmaType)_type)); - DefType containingType = _type.ContainingType; if (containingType != null) dependencies.Add(factory.TypeMetadata((MetadataType)containingType), "Containing type of a reflectable type"); @@ -102,6 +100,13 @@ public override IEnumerable GetStaticDependencies(NodeFacto return dependencies; } + public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) + { + var dependencies = new List(); + CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ((EcmaType)_type)); + return dependencies; + } + /// /// Decomposes a constructed type into individual units that will be needed to /// express the constructed type in metadata. @@ -183,9 +188,8 @@ protected override void OnMarked(NodeFactory factory) public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; - public override bool HasConditionalStaticDependencies => false; + public override bool HasConditionalStaticDependencies => true; public override bool StaticDependenciesAreComputed => true; - public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs index bc4809e5dd8e53..557fd8fbfefcc8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs @@ -6,6 +6,7 @@ using System.Reflection; using Mono.Linker.Tests.Cases.DataFlow; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; [assembly: KeptAttributeAttribute(typeof(AttributeConstructorDataflow.KeepsPublicPropertiesAttribute))] [assembly: ExpectedWarning("IL2026", "--ClassWithKeptPublicProperties--")] @@ -15,6 +16,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow { [Kept] [ExpectedNoWarnings] + [SetupIlcWholeProgramAnalysis] class AttributeConstructorDataflow { [KeptAttributeAttribute(typeof(KeepsPublicConstructorAttribute))] @@ -30,6 +32,7 @@ public static void Main() { typeof(AttributeConstructorDataflow).GetMethod("Main").GetCustomAttribute(typeof(KeepsPublicConstructorAttribute)); typeof(AttributeConstructorDataflow).GetMethod("Main").GetCustomAttribute(typeof(KeepsPublicMethodsAttribute)); + Assembly.GetEntryAssembly().GetCustomAttributes(); AllOnSelf.Test(); AnnotationOnTypeArray.Test(); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs index 4e4326d5bf0685..7a50cce7174b4a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs @@ -5,11 +5,13 @@ 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.DataFlow { [Kept] [ExpectedNoWarnings] + [SetupIlcWholeProgramAnalysis] class AttributeFieldDataflow { public static void Main() diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs index 5cfbee709e687a..b3c301044eafa8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs @@ -5,11 +5,13 @@ 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.DataFlow { [Kept] [ExpectedNoWarnings] + [SetupIlcWholeProgramAnalysis] class AttributePropertyDataflow { public static void Main() diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs index 1bfa672aef84a7..ca563d40dd8467 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs @@ -4,9 +4,11 @@ using System; using System.Diagnostics.CodeAnalysis; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { + [SetupIlcWholeProgramAnalysis] [ExpectedNoWarnings] [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Applying DAM PublicMethods on an array will mark Array.CreateInstance which has RDC on it")] [KeptAttributeAttribute(typeof(UnconditionalSuppressMessageAttribute))] @@ -175,7 +177,7 @@ static void TestArrayInAttributeParameter() { // Have to access the method through reflection, otherwise NativeAOT will remove all attributes on it // since they're not accessible. - typeof(ComplexTypeHandling).GetMethod(nameof(TestArrayInAttributeParameterImpl), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).Invoke(null, new object[] { }); + typeof(ComplexTypeHandling).GetMethod(nameof(TestArrayInAttributeParameterImpl), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetCustomAttributes(false); } [Kept] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/NewConstraintOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/NewConstraintOnClass.cs index 3dd1f4f487fb9a..6ecbdd662604cc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/NewConstraintOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/NewConstraintOnClass.cs @@ -130,8 +130,8 @@ public static void Test() namespace System.Runtime.CompilerServices { - [Kept] - [KeptMember(".ctor()")] + [Kept(By = Tool.Trimmer)] + [KeptMember(".ctor()", By = Tool.Trimmer)] public partial class IsUnmanagedAttribute { }