From 854de86fbb91ec0353a82fb4e4a08b7d0968189b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 12 Aug 2025 16:53:16 +0200 Subject: [PATCH 1/2] Trim custom attributes 1. To be able to read custom attributes at runtime, we need to use the internal metadata APIs 2. When the internal metadata API is not used, we know nobody could be reading the attributes 3. Make custom attribute emission conditional on the presence of the reading API in the graph 4. Use separate conditions for different kinds of attributes - fields, types, methods, etc. In practice, this doesn't help much outside of Hello World scenarios because custom attribute reading at runtime happens through a virtual method on `MemberInfo`. So if e.g. `PropertyInfo` is allocated and somebody calls `Type.GetCustomAttributes` (which is `MemberInfo.GetCustomAttributes` virtual), we include code to read attributes on properties too. This is a solvable problem if we learn to do devirtualization during scanning phase; then we can reap more benefit from this. --- ...CustomAttributeBasedDependencyAlgorithm.cs | 55 +++++++++++++------ .../DependencyAnalysis/FieldMetadataNode.cs | 13 +++-- .../DependencyAnalysis/MethodMetadataNode.cs | 13 +++-- .../DependencyAnalysis/ModuleMetadataNode.cs | 12 ++-- .../DependencyAnalysis/TypeMetadataNode.cs | 12 ++-- 5 files changed, 71 insertions(+), 34 deletions(-) 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; } } From e8b839f499cd6675288d0ef757860fff62240832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Wed, 13 Aug 2025 09:40:31 +0200 Subject: [PATCH 2/2] Fix trimming tests --- .../DataFlow/AttributeConstructorDataflow.cs | 3 +++ .../DataFlow/AttributeFieldDataflow.cs | 2 ++ .../DataFlow/AttributePropertyDataflow.cs | 2 ++ .../Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs | 4 +++- .../Mono.Linker.Tests.Cases/Generics/NewConstraintOnClass.cs | 4 ++-- 5 files changed, 12 insertions(+), 3 deletions(-) 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 { }