diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs index d6d4526e5c771a..deb9474117f478 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs @@ -476,7 +476,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp { if (methodBody.GetObject(reader.ReadILToken()) is MethodDesc methodOperand) { - HandleMethodReflectionAccess(methodBody, offset, methodOperand); + HandleMethodTokenAccess(methodBody, offset, methodOperand); TrackNestedFunctionReference(methodOperand, ref interproceduralState); } @@ -537,7 +537,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp { if (methodBody.GetObject(reader.ReadILToken()) is MethodDesc methodOperand) { - HandleMethodReflectionAccess(methodBody, offset, methodOperand); + HandleMethodTokenAccess(methodBody, offset, methodOperand); } PopUnknown(currentStack, 1, methodBody, offset); @@ -963,14 +963,14 @@ private void ScanLdtoken(MethodIL methodBody, int offset, object operand, Stack< } } - HandleTypeReflectionAccess(methodBody, offset, type); + HandleTypeTokenAccess(methodBody, offset, type); } else if (operand is MethodDesc method) { StackSlot slot = new StackSlot(new RuntimeMethodHandleValue(method)); currentStack.Push(slot); - HandleMethodReflectionAccess(methodBody, offset, method); + HandleMethodTokenAccess(methodBody, offset, method); } else { @@ -978,7 +978,7 @@ private void ScanLdtoken(MethodIL methodBody, int offset, object operand, Stack< PushUnknown(currentStack); - HandleFieldReflectionAccess(methodBody, offset, (FieldDesc)operand); + HandleFieldTokenAccess(methodBody, offset, (FieldDesc)operand); } } @@ -1248,19 +1248,19 @@ protected void AssignRefAndOutParameters( } /// - /// Called when type is accessed directly (basically only ldtoken) + /// Called when type is accessed directly by its token (so creating a RuntimeHandle) /// - protected abstract void HandleTypeReflectionAccess(MethodIL methodBody, int offset, TypeDesc accessedType); + protected abstract void HandleTypeTokenAccess(MethodIL methodBody, int offset, TypeDesc accessedType); /// - /// Called to handle reflection access to a method without any other specifics (ldtoken or ldftn for example) + /// Called to handle access to a method by its token (so creating a RuntimeHandle) /// - protected abstract void HandleMethodReflectionAccess(MethodIL methodBody, int offset, MethodDesc accessedMethod); + protected abstract void HandleMethodTokenAccess(MethodIL methodBody, int offset, MethodDesc accessedMethod); /// - /// Called to handle reflection access to a field without any other specifics (ldtoken for example) + /// Called to handle access to a field by its token (so creating a RuntimeHandle) /// - protected abstract void HandleFieldReflectionAccess(MethodIL methodBody, int offset, FieldDesc accessedField); + protected abstract void HandleFieldTokenAccess(MethodIL methodBody, int offset, FieldDesc accessedField); private void HandleCall( MethodIL callingMethodBody, diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs index 4ecabf6aad6d64..d32757d162d80b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs @@ -31,6 +31,13 @@ public class ReflectionMarker public FlowAnnotations Annotations { get; } public DependencyList Dependencies { get => _dependencies; } + internal enum AccessKind + { + Unspecified, + DynamicallyAccessedMembersMark, + TokenAccess + } + public ReflectionMarker(Logger logger, NodeFactory factory, FlowAnnotations annotations, MetadataType? typeHierarchyDataFlowOrigin, bool enabled) { _logger = logger; @@ -47,28 +54,28 @@ internal void MarkTypeForDynamicallyAccessedMembers(in MessageOrigin origin, Typ foreach (var member in typeDefinition.GetDynamicallyAccessedMembers(requiredMemberTypes, declaredOnly)) { - MarkTypeSystemEntity(origin, member, reason); + MarkTypeSystemEntity(origin, member, reason, AccessKind.DynamicallyAccessedMembersMark); } } - internal void MarkTypeSystemEntity(in MessageOrigin origin, TypeSystemEntity entity, string reason) + internal void MarkTypeSystemEntity(in MessageOrigin origin, TypeSystemEntity entity, string reason, AccessKind accessKind = AccessKind.Unspecified) { switch (entity) { case MethodDesc method: - MarkMethod(origin, method, reason); + MarkMethod(origin, method, reason, accessKind); break; case FieldDesc field: - MarkField(origin, field, reason); + MarkField(origin, field, reason, accessKind); break; case MetadataType nestedType: - MarkType(origin, nestedType, reason); + MarkType(origin, nestedType, reason, accessKind); break; case PropertyPseudoDesc property: - MarkProperty(origin, property, reason); + MarkProperty(origin, property, reason, accessKind); break; case EventPseudoDesc @event: - MarkEvent(origin, @event, reason); + MarkEvent(origin, @event, reason, accessKind); break; // case InterfaceImplementation // Nothing to do currently as Native AOT will preserve all interfaces on a preserved type @@ -107,7 +114,7 @@ internal bool TryResolveTypeNameAndMark(string typeName, in DiagnosticContext di return true; } - internal void MarkType(in MessageOrigin origin, TypeDesc type, string reason) + internal void MarkType(in MessageOrigin origin, TypeDesc type, string reason, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; @@ -115,27 +122,27 @@ internal void MarkType(in MessageOrigin origin, TypeDesc type, string reason) RootingHelpers.TryGetDependenciesForReflectedType(ref _dependencies, Factory, type, reason); } - internal void MarkMethod(in MessageOrigin origin, MethodDesc method, string reason) + internal void MarkMethod(in MessageOrigin origin, MethodDesc method, string reason, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; - CheckAndWarnOnReflectionAccess(origin, method); + CheckAndWarnOnReflectionAccess(origin, method, accessKind); RootingHelpers.TryGetDependenciesForReflectedMethod(ref _dependencies, Factory, method, reason); } - internal void MarkField(in MessageOrigin origin, FieldDesc field, string reason) + internal void MarkField(in MessageOrigin origin, FieldDesc field, string reason, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; - CheckAndWarnOnReflectionAccess(origin, field); + CheckAndWarnOnReflectionAccess(origin, field, accessKind); RootingHelpers.TryGetDependenciesForReflectedField(ref _dependencies, Factory, field, reason); } - internal void MarkProperty(in MessageOrigin origin, PropertyPseudoDesc property, string reason) + internal void MarkProperty(in MessageOrigin origin, PropertyPseudoDesc property, string reason, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; @@ -146,7 +153,7 @@ internal void MarkProperty(in MessageOrigin origin, PropertyPseudoDesc property, MarkMethod(origin, property.SetMethod, reason); } - private void MarkEvent(in MessageOrigin origin, EventPseudoDesc @event, string reason) + private void MarkEvent(in MessageOrigin origin, EventPseudoDesc @event, string reason, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; @@ -209,86 +216,137 @@ internal void MarkStaticConstructor(in MessageOrigin origin, TypeDesc type, stri } } - internal void CheckAndWarnOnReflectionAccess(in MessageOrigin origin, TypeSystemEntity entity) + internal void CheckAndWarnOnReflectionAccess(in MessageOrigin origin, TypeSystemEntity entity, AccessKind accessKind = AccessKind.Unspecified) { if (!_enabled) return; + if (_typeHierarchyDataFlowOrigin is not null) + { + ReportWarningsForTypeHierarchyReflectionAccess(origin, entity); + } + else + { + ReportWarningsForReflectionAccess(origin, entity, accessKind); + } + } + + private void ReportWarningsForReflectionAccess(in MessageOrigin origin, TypeSystemEntity entity, AccessKind accessKind) + { + Debug.Assert(entity is MethodDesc or FieldDesc); + // Note that we're using `ShouldSuppressAnalysisWarningsForRequires` instead of `DoesMemberRequire`. // This is because reflection access is actually problematic on all members which are in a "requires" scope // so for example even instance methods. See for example https://github.com/dotnet/linker/issues/3140 - it's possible // to call a method on a "null" instance via reflection. if (_logger.ShouldSuppressAnalysisWarningsForRequires(entity, DiagnosticUtilities.RequiresUnreferencedCodeAttribute, out CustomAttributeValue? requiresAttribute)) { - if (_typeHierarchyDataFlowOrigin is not null) - { - _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithRequiresUnreferencedCode, - _typeHierarchyDataFlowOrigin.GetDisplayName(), - entity.GetDisplayName(), - MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeMessage(requiresAttribute.Value)), - MessageFormat.FormatRequiresAttributeUrlArg(DiagnosticUtilities.GetRequiresAttributeUrl(requiresAttribute.Value))); - } - else - { + if (!ShouldSkipWarningsForOverride(entity, accessKind)) ReportRequires(origin, entity, DiagnosticUtilities.RequiresUnreferencedCodeAttribute, requiresAttribute.Value); - } } if (_logger.ShouldSuppressAnalysisWarningsForRequires(entity, DiagnosticUtilities.RequiresAssemblyFilesAttribute, out requiresAttribute)) { - if (_typeHierarchyDataFlowOrigin is not null) - { - // For now we decided to not report single-file warnings due to type hierarchy marking. - // It is considered too complex to figure out for the user and the likelihood of this - // causing problems is pretty low. - } - else - { + if (!ShouldSkipWarningsForOverride(entity, accessKind)) ReportRequires(origin, entity, DiagnosticUtilities.RequiresAssemblyFilesAttribute, requiresAttribute.Value); - } } if (_logger.ShouldSuppressAnalysisWarningsForRequires(entity, DiagnosticUtilities.RequiresDynamicCodeAttribute, out requiresAttribute)) { - if (_typeHierarchyDataFlowOrigin is not null) - { - // For now we decided to not report dynamic code warnings due to type hierarchy marking. - // It is considered too complex to figure out for the user and the likelihood of this - // causing problems is pretty low. - } - else - { + if (!ShouldSkipWarningsForOverride(entity, accessKind)) ReportRequires(origin, entity, DiagnosticUtilities.RequiresDynamicCodeAttribute, requiresAttribute.Value); - } } - if (!Annotations.ShouldWarnWhenAccessedForReflection(entity)) + // Below is about accessing DAM annotated members, so only RUC is applicable as a suppression scope + if (_logger.ShouldSuppressAnalysisWarningsForRequires(origin.MemberDefinition, DiagnosticUtilities.RequiresUnreferencedCodeAttribute)) return; - if (_typeHierarchyDataFlowOrigin is not null) + bool isReflectionAccessCoveredByDAM = Annotations.ShouldWarnWhenAccessedForReflection(entity); + if (isReflectionAccessCoveredByDAM && !ShouldSkipWarningsForOverride(entity, accessKind)) { - // Don't check whether the current scope is a RUC type or RUC method because these warnings - // are not suppressed in RUC scopes. Here the scope represents the DynamicallyAccessedMembers - // annotation on a type, not a callsite which uses the annotation. We always want to warn about - // possible reflection access indicated by these annotations. - _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithDynamicallyAccessedMembers, - _typeHierarchyDataFlowOrigin.GetDisplayName(), entity.GetDisplayName()); + if (entity is MethodDesc) + _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection, entity.GetDisplayName()); + else + _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersFieldAccessedViaReflection, entity.GetDisplayName()); } - else + + // We decided to not warn on reflection access to compiler-generated methods: + // https://github.com/dotnet/runtime/issues/85042 + + // All override methods should have the same annotations as their base methods + // (else we will produce warning IL2046 or IL2092 or some other warning). + // When marking override methods via DynamicallyAccessedMembers, we should only issue a warning for the base method. + // PERF: Avoid precomputing this as this method is relatively expensive. Only call it once we're about to produce a warning. + static bool ShouldSkipWarningsForOverride(TypeSystemEntity entity, AccessKind accessKind) + { + if (accessKind != AccessKind.DynamicallyAccessedMembersMark || entity is not MethodDesc method || !method.IsVirtual) + return false; + + return MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(method) != method; + } + } + + private void ReportWarningsForTypeHierarchyReflectionAccess(MessageOrigin origin, TypeSystemEntity entity) + { + Debug.Assert(entity is MethodDesc or FieldDesc); + + // Don't check whether the current scope is a RUC type or RUC method because these warnings + // are not suppressed in RUC scopes. Here the scope represents the DynamicallyAccessedMembers + // annotation on a type, not a callsite which uses the annotation. We always want to warn about + // possible reflection access indicated by these annotations. + + Debug.Assert(_typeHierarchyDataFlowOrigin != null); + + static bool IsDeclaredWithinType(TypeSystemEntity member, TypeDesc type) { - if (!_logger.ShouldSuppressAnalysisWarningsForRequires(origin.MemberDefinition, DiagnosticUtilities.RequiresUnreferencedCodeAttribute)) + TypeDesc owningType = member.GetOwningType(); + while (owningType != null) { - if (entity is FieldDesc) - { - _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersFieldAccessedViaReflection, entity.GetDisplayName()); - } - else - { - Debug.Assert(entity is MethodDesc); - - _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection, entity.GetDisplayName()); - } + if (owningType == type) + return true; + + owningType = owningType.GetOwningType(); } + return false; + } + + var reportOnMember = IsDeclaredWithinType(entity, _typeHierarchyDataFlowOrigin); + if (reportOnMember) + origin = new MessageOrigin(entity); + + // For now we decided to not report single-file or dynamic-code warnings due to type hierarchy marking. + // It is considered too complex to figure out for the user and the likelihood of this + // causing problems is pretty low. + + bool isReflectionAccessCoveredByRUC = _logger.ShouldSuppressAnalysisWarningsForRequires(entity, DiagnosticUtilities.RequiresUnreferencedCodeAttribute, out CustomAttributeValue? requiresUnreferencedCodeAttribute); + if (isReflectionAccessCoveredByRUC && !ShouldSkipWarningsForOverride(entity)) + { + var id = reportOnMember ? DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberWithRequiresUnreferencedCode : DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithRequiresUnreferencedCode; + _logger.LogWarning(origin, id, _typeHierarchyDataFlowOrigin.GetDisplayName(), + entity.GetDisplayName(), + MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeMessage(requiresUnreferencedCodeAttribute!.Value)), + MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeUrl(requiresUnreferencedCodeAttribute!.Value))); + } + + bool isReflectionAccessCoveredByDAM = Annotations.ShouldWarnWhenAccessedForReflection(entity); + if (isReflectionAccessCoveredByDAM && !ShouldSkipWarningsForOverride(entity)) + { + var id = reportOnMember ? DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberWithDynamicallyAccessedMembers : DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithDynamicallyAccessedMembers; + _logger.LogWarning(origin, id, _typeHierarchyDataFlowOrigin.GetDisplayName(), entity.GetDisplayName()); + } + + // We decided to not warn on reflection access to compiler-generated methods: + // https://github.com/dotnet/runtime/issues/85042 + + // All override methods should have the same annotations as their base methods + // (else we will produce warning IL2046 or IL2092 or some other warning). + // When marking override methods via DynamicallyAccessedMembers, we should only issue a warning for the base method. + static bool ShouldSkipWarningsForOverride(TypeSystemEntity entity) + { + if (entity is not MethodDesc method || !method.IsVirtual) + return false; + + return MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(method) != method; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs index b0979861ef166a..79c0cf011bf9ba 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs @@ -135,7 +135,42 @@ public static DependencyList ProcessTypeGetTypeDataflow(NodeFactory factory, Flo DynamicallyAccessedMemberTypes annotation = flowAnnotations.GetTypeAnnotation(type); Debug.Assert(annotation != DynamicallyAccessedMemberTypes.None); var reflectionMarker = new ReflectionMarker(logger, factory, flowAnnotations, typeHierarchyDataFlowOrigin: type, enabled: true); - reflectionMarker.MarkTypeForDynamicallyAccessedMembers(new MessageOrigin(type), type, annotation, type.GetDisplayName()); + + // We need to apply annotations to this type, and its base/interface types (recursively) + // But the annotations on base/interfaces may already be applied so we don't need to apply those + // again (and should avoid doing so as it would produce extra warnings). + MessageOrigin origin = new MessageOrigin(type); + if (type.HasBaseType) + { + var baseAnnotation = flowAnnotations.GetTypeAnnotation(type.BaseType); + var annotationToApplyToBase = Annotations.GetMissingMemberTypes(annotation, baseAnnotation); + + // Apply any annotations that didn't exist on the base type to the base type. + // This may produce redundant warnings when the annotation is DAMT.All or DAMT.PublicConstructors and the base already has a + // subset of those annotations. + reflectionMarker.MarkTypeForDynamicallyAccessedMembers(origin, type.BaseType, annotationToApplyToBase, type.GetDisplayName(), declaredOnly: false); + } + + // Most of the DynamicallyAccessedMemberTypes don't select members on interfaces. We only need to apply + // annotations to interfaces separately if dealing with DAMT.All or DAMT.Interfaces. + if (annotation.HasFlag(DynamicallyAccessedMemberTypes.Interfaces)) + { + var annotationToApplyToInterfaces = annotation == DynamicallyAccessedMemberTypes.All ? annotation : DynamicallyAccessedMemberTypes.Interfaces; + foreach (var iface in type.RuntimeInterfaces) + { + if (flowAnnotations.GetTypeAnnotation(iface).HasFlag(annotationToApplyToInterfaces)) + continue; + + // Apply All or Interfaces to the interface type. + // DAMT.All may produce redundant warnings from implementing types, when the interface type already had some annotations. + reflectionMarker.MarkTypeForDynamicallyAccessedMembers(origin, iface, annotationToApplyToInterfaces, type.GetDisplayName(), declaredOnly: false); + } + } + + // The annotations this type inherited from its base types or interfaces should not produce + // warnings on the respective base/interface members, since those are already covered by applying + // the annotations to those types. So we only need to handle the members directly declared on this type. + reflectionMarker.MarkTypeForDynamicallyAccessedMembers(new MessageOrigin(type), type, annotation, type.GetDisplayName(), declaredOnly: true); return reflectionMarker.Dependencies; } @@ -193,7 +228,7 @@ protected override void HandleStoreParameter(MethodIL methodBody, int offset, Me protected override void HandleStoreMethodReturnValue(MethodIL methodBody, int offset, MethodReturnValue returnValue, MultiValue valueToStore) => HandleStoreValueWithDynamicallyAccessedMembers(methodBody, offset, returnValue, valueToStore, returnValue.Method.GetDisplayName()); - protected override void HandleTypeReflectionAccess(MethodIL methodBody, int offset, TypeDesc accessedType) + protected override void HandleTypeTokenAccess(MethodIL methodBody, int offset, TypeDesc accessedType) { // Note that ldtoken alone is technically a reflection access to the type // it doesn't lead to full reflection marking of the type @@ -204,20 +239,20 @@ protected override void HandleTypeReflectionAccess(MethodIL methodBody, int offs ProcessGenericArgumentDataFlow(accessedType); } - protected override void HandleMethodReflectionAccess(MethodIL methodBody, int offset, MethodDesc accessedMethod) + protected override void HandleMethodTokenAccess(MethodIL methodBody, int offset, MethodDesc accessedMethod) { _origin = _origin.WithInstructionOffset(methodBody, offset); - TrimAnalysisPatterns.Add(new TrimAnalysisReflectionAccessPattern(accessedMethod, _origin)); + TrimAnalysisPatterns.Add(new TrimAnalysisTokenAccessPattern(accessedMethod, _origin)); ProcessGenericArgumentDataFlow(accessedMethod); } - protected override void HandleFieldReflectionAccess(MethodIL methodBody, int offset, FieldDesc accessedField) + protected override void HandleFieldTokenAccess(MethodIL methodBody, int offset, FieldDesc accessedField) { _origin = _origin.WithInstructionOffset(methodBody, offset); - TrimAnalysisPatterns.Add(new TrimAnalysisReflectionAccessPattern(accessedField, _origin)); + TrimAnalysisPatterns.Add(new TrimAnalysisTokenAccessPattern(accessedField, _origin)); ProcessGenericArgumentDataFlow(accessedField); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisPatternStore.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisPatternStore.cs index 64c539b0346d30..258f2bcfef26cc 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisPatternStore.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisPatternStore.cs @@ -15,7 +15,7 @@ public readonly struct TrimAnalysisPatternStore { private readonly Dictionary<(MessageOrigin, bool), TrimAnalysisAssignmentPattern> AssignmentPatterns; private readonly Dictionary MethodCallPatterns; - private readonly Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisReflectionAccessPattern> ReflectionAccessPatterns; + private readonly Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisTokenAccessPattern> TokenAccessPatterns; private readonly Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisGenericInstantiationAccessPattern> GenericInstantiations; private readonly Dictionary<(MessageOrigin, FieldDesc), TrimAnalysisFieldAccessPattern> FieldAccessPatterns; private readonly ValueSetLattice Lattice; @@ -25,7 +25,7 @@ public TrimAnalysisPatternStore(ValueSetLattice lattice, Logger log { AssignmentPatterns = new Dictionary<(MessageOrigin, bool), TrimAnalysisAssignmentPattern>(); MethodCallPatterns = new Dictionary(); - ReflectionAccessPatterns = new Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisReflectionAccessPattern>(); + TokenAccessPatterns = new Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisTokenAccessPattern>(); GenericInstantiations = new Dictionary<(MessageOrigin, TypeSystemEntity), TrimAnalysisGenericInstantiationAccessPattern>(); FieldAccessPatterns = new Dictionary<(MessageOrigin, FieldDesc), TrimAnalysisFieldAccessPattern>(); Lattice = lattice; @@ -60,9 +60,9 @@ public void Add(TrimAnalysisMethodCallPattern pattern) MethodCallPatterns[pattern.Origin] = pattern.Merge(Lattice, existingPattern); } - public void Add(TrimAnalysisReflectionAccessPattern pattern) + public void Add(TrimAnalysisTokenAccessPattern pattern) { - ReflectionAccessPatterns.TryAdd((pattern.Origin, pattern.Entity), pattern); + TokenAccessPatterns.TryAdd((pattern.Origin, pattern.Entity), pattern); // No Merge - there's nothing to merge since this pattern is uniquely identified by both the origin and the entity // and there's only one way to "access" a generic instantiation. @@ -92,7 +92,7 @@ public void MarkAndProduceDiagnostics(ReflectionMarker reflectionMarker) foreach (var pattern in MethodCallPatterns.Values) pattern.MarkAndProduceDiagnostics(reflectionMarker, _logger); - foreach (var pattern in ReflectionAccessPatterns.Values) + foreach (var pattern in TokenAccessPatterns.Values) pattern.MarkAndProduceDiagnostics(reflectionMarker, _logger); foreach (var pattern in GenericInstantiations.Values) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisReflectionAccessPattern.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisTokenAccessPattern.cs similarity index 76% rename from src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisReflectionAccessPattern.cs rename to src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisTokenAccessPattern.cs index 8f40b94c02d811..6d7308235cfbf1 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisReflectionAccessPattern.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisTokenAccessPattern.cs @@ -9,30 +9,30 @@ namespace ILCompiler.Dataflow { - public readonly record struct TrimAnalysisReflectionAccessPattern + public readonly record struct TrimAnalysisTokenAccessPattern { public TypeSystemEntity Entity { init; get; } public MessageOrigin Origin { init; get; } - internal TrimAnalysisReflectionAccessPattern(TypeSystemEntity entity, MessageOrigin origin) + internal TrimAnalysisTokenAccessPattern(TypeSystemEntity entity, MessageOrigin origin) { Entity = entity; Origin = origin; } // No Merge - there's nothing to merge since this pattern is uniquely identified by both the origin and the entity - // and there's only one way to "reflection access" an entity. + // and there's only one way to access entity by its handle. public void MarkAndProduceDiagnostics(ReflectionMarker reflectionMarker, Logger logger) { switch (Entity) { case MethodDesc method: - reflectionMarker.CheckAndWarnOnReflectionAccess(Origin, method); + reflectionMarker.CheckAndWarnOnReflectionAccess(Origin, method, ReflectionMarker.AccessKind.TokenAccess); break; case FieldDesc field: - reflectionMarker.CheckAndWarnOnReflectionAccess(Origin, field); + reflectionMarker.CheckAndWarnOnReflectionAccess(Origin, field, ReflectionMarker.AccessKind.TokenAccess); break; default: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs index 13942b8d45c40f..aa7a3ccad51f1b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs @@ -149,11 +149,6 @@ public void LogError(TypeSystemEntity origin, DiagnosticId id, params string[] a internal bool IsWarningSuppressed(int code, MessageOrigin origin) { - // This is causing too much noise - // https://github.com/dotnet/runtime/issues/81156 - if (code == 2110 || code == 2111 || code == 2113 || code == 2115) - return true; - if (_suppressedWarnings.Contains(code)) return true; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj index 3e71f63059fcbf..f62b3b66557f3f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj @@ -383,7 +383,7 @@ - + Compiler\Dataflow\TypeNameParser.cs diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs index fc9b8f26650bc5..2eb46309c7d379 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs @@ -34,6 +34,11 @@ public static IEnumerable LinkXml() return TestNamesBySuiteName(); } + public static IEnumerable Reflection () + { + return TestNamesBySuiteName (); + } + public static IEnumerable Repro () { return TestNamesBySuiteName (); diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs index add1386c9bad88..4e3901f2697069 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs @@ -37,6 +37,20 @@ public void LinkXml (string t) Run (t); } + [Theory] + [MemberData (nameof (TestDatabase.Reflection), MemberType = typeof (TestDatabase))] + public void Reflection (string t) + { + switch (t) { + case "TypeHierarchyReflectionWarnings": + Run (t); + break; + default: + // Skip the rest for now + break; + } + } + [Theory] [MemberData (nameof (TestDatabase.Repro), MemberType = typeof (TestDatabase))] public void Repro (string t) diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyQualifiedToken.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyQualifiedToken.cs index af39d8d687883c..01693b1bdc0bdb 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyQualifiedToken.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyQualifiedToken.cs @@ -9,6 +9,7 @@ using Internal.TypeSystem.Ecma; using Internal.TypeSystem; using Mono.Cecil; +using MetadataType = Internal.TypeSystem.MetadataType; namespace Mono.Linker.Tests.TestCasesRunner { @@ -27,6 +28,7 @@ public AssemblyQualifiedToken (TypeSystemEntity entity) => PropertyPseudoDesc property => (((EcmaType) property.OwningType).Module.Assembly.GetName ().Name, MetadataTokens.GetToken (property.Handle)), EventPseudoDesc @event => (((EcmaType) @event.OwningType).Module.Assembly.GetName ().Name, MetadataTokens.GetToken (@event.Handle)), ILStubMethod => (null, 0), // Ignore compiler generated methods + MetadataType mt when mt.GetType().Name == "BoxedValueType" => (null, 0), _ => throw new NotSupportedException ($"The infra doesn't support getting a token for {entity} yet.") }; diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs index 4d694b7ae0061c..cb752664e81fe6 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs @@ -80,7 +80,7 @@ public virtual void Check (ILCompilerTestCaseResult testResult) PerformOutputAssemblyChecks (original, testResult); PerformOutputSymbolChecks (original, testResult); - if (!HasAttribute (original.MainModule.GetType (testResult.TestCase.ReconstructedFullTypeName), nameof (SkipKeptItemsValidationAttribute))) { + if (!HasActiveSkipKeptItemsValidationAttribute (original.MainModule.GetType (testResult.TestCase.ReconstructedFullTypeName))) { CreateAssemblyChecker (original, testResult).Verify (); } } @@ -89,6 +89,16 @@ public virtual void Check (ILCompilerTestCaseResult testResult) } finally { _originalsResolver.Dispose (); } + + bool HasActiveSkipKeptItemsValidationAttribute(ICustomAttributeProvider provider) + { + if (TryGetCustomAttribute(provider, nameof(SkipKeptItemsValidationAttribute), out var attribute)) { + object? keptBy = attribute.GetPropertyValue (nameof (SkipKeptItemsValidationAttribute.By)); + return keptBy is null ? true : ((Tool) keptBy).HasFlag (Tool.NativeAot); + } + + return false; + } } protected virtual AssemblyChecker CreateAssemblyChecker (AssemblyDefinition original, ILCompilerTestCaseResult testResult) @@ -316,8 +326,8 @@ private void VerifyLoggedMessages (AssemblyDefinition original, TestLogWriter lo loggedMessages.Remove (loggedMessage); break; } - if (methodDesc.Name == ".ctor" && - methodDesc.OwningType.ToString () == expectedMember.FullName) { + if (methodDesc.IsConstructor && + new AssemblyQualifiedToken (methodDesc.OwningType).Equals(new AssemblyQualifiedToken (expectedMember))) { expectedWarningFound = true; loggedMessages.Remove (loggedMessage); break; @@ -400,10 +410,13 @@ static bool LogMessageHasSameOriginMember (MessageContainer mc, ICustomAttribute Debug.Assert (origin != null); if (origin?.MemberDefinition == null) return false; + if (origin?.MemberDefinition is IAssemblyDesc asm) + return expectedOriginProvider is AssemblyDefinition expectedAsm && asm.GetName().Name == expectedAsm.Name.Name; + if (expectedOriginProvider is not IMemberDefinition expectedOriginMember) return false; - var actualOriginToken = new AssemblyQualifiedToken (origin.Value.MemberDefinition); + var actualOriginToken = new AssemblyQualifiedToken (origin!.Value.MemberDefinition); var expectedOriginToken = new AssemblyQualifiedToken (expectedOriginMember); if (actualOriginToken.Equals (expectedOriginToken)) return true; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs index deb54564a8d0a5..5a5fca7df33753 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs @@ -9,5 +9,7 @@ namespace Mono.Linker.Tests.Cases.Expectations.Assertions public class SkipKeptItemsValidationAttribute : BaseExpectedLinkedBehaviorAttribute { public SkipKeptItemsValidationAttribute () { } + + public Tool By { get; set; } = Tool.TrimmerAnalyzerAndNativeAot; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs index 5029df77743ce7..baea4bfcbf43d9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs @@ -18,7 +18,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] [SkipKeptItemsValidation] [ExpectedNoWarnings] [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "These tests are not targeted at AOT scenarios")] @@ -58,8 +57,8 @@ static void ReflectionReadOnly () typeof (AnnotatedField).GetField ("_annotatedField").GetValue (null); } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicFields, typeof (AnnotatedField))] static void DynamicDependency () { @@ -71,8 +70,8 @@ static void DynamicDependencySuppressedByRUC () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (nameof (_annotatedField), typeof (AnnotatedField))] static void DynamicDependencyByName () { @@ -133,7 +132,7 @@ static void PotentialWriteAccess (ref Type type) } // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2110", nameof (AnnotatedField._annotatedField), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2110", nameof (AnnotatedField._annotatedField), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void LdToken () { Expression a = () => PotentialWriteAccess (ref _annotatedField); @@ -189,8 +188,8 @@ static void AnnotatedAttributeConstructor () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodParameters))] static void DynamicDependency () { @@ -202,8 +201,8 @@ static void DynamicDependencySuppressedByRUC () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (nameof (MethodWithSingleAnnotatedParameter), typeof (AnnotatedMethodParameters))] static void DynamicDependencyByName () { @@ -221,8 +220,8 @@ static void DynamicallyAccessedMembersSuppressedByRUC () typeof (AnnotatedMethodParameters).RequiresPublicMethods (); } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void Ldftn () { var _ = new Action (AnnotatedMethodParameters.MethodWithSingleAnnotatedParameter); @@ -233,8 +232,8 @@ interface IWithAnnotatedMethod public void AnnotatedMethod ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type type); } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void Ldvirtftn () { IWithAnnotatedMethod instance = null; @@ -264,7 +263,7 @@ static void DynamicallyAccessedMembersAll2 () } // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL2067", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Analyzer)] static void LdToken () { @@ -325,8 +324,8 @@ static void ReflectionOnVirtualSuppressedByRUC () typeof (AnnotatedMethodReturnValue).GetMethod (nameof (VirtualMethodWithAnnotatedReturnValue)).Invoke (null, null); } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodReturnValue))] static void DynamicDependency () { @@ -348,8 +347,8 @@ static void DynamicDependencyByNameOnInstance () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (nameof (VirtualMethodWithAnnotatedReturnValue), typeof (AnnotatedMethodReturnValue))] static void DynamicDependencyByNameOnVirtual () { @@ -377,8 +376,8 @@ static void LdftnOnInstance () var _ = new Func ((new AnnotatedMethodReturnValue ()).InstanceMethodWithAnnotatedReturnValue); } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void LdftnOnVirtual () { var _ = new Func ((new AnnotatedMethodReturnValue ()).VirtualMethodWithAnnotatedReturnValue); @@ -390,7 +389,7 @@ static void LdTokenOnStatic () } // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void LdTokenOnVirtual () { Expression> _ = (a) => a.VirtualMethodWithAnnotatedReturnValue (); @@ -433,7 +432,7 @@ class AnnotatedProperty public virtual Type VirtualProperty4WithAnnotation { get => null; set { value.ToString (); } } public static Type Property5WithAnnotationOnMembers { - [ExpectedWarning ("IL2078", nameof (Property5WithAnnotationOnMembers) + ".get", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2078", nameof (Property5WithAnnotationOnMembers) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] get; [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] @@ -501,14 +500,14 @@ static void AnnotatedAttributeProperty () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 - [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set", ProducedBy = Tool.Trimmer)] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 + [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicProperties, typeof (AnnotatedProperty))] static void DynamicDependency () { @@ -592,14 +591,14 @@ static void DynamicallyAccessedMembersAll2 () } // Analyzer doesn't produce this warning https://github.com/dotnet/linker/issues/2628 - [ExpectedWarning ("IL2110", nameof (Property1WithAnnotation), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2110", nameof (Property1WithAnnotation), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void DynamicallyAccessedFields () { typeof (AnnotatedProperty).RequiresNonPublicFields (); } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation), ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void LdToken () { Expression> _ = () => Property1WithAnnotation; @@ -697,8 +696,8 @@ public static void GenericMethodWithAnnotation ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (GenericWithAnnotatedMethod.AnnotatedMethod), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (GenericWithAnnotatedMethod.AnnotatedMethod), ProducedBy = Tool.Trimmer | Tool.NativeAot)] public static void GenericTypeWithStaticMethodViaLdftn () { var _ = new Action (GenericWithAnnotatedMethod.AnnotatedMethod); @@ -716,8 +715,8 @@ public static void GenericMethodWithAnnotationDirectCall () GenericMethodWithAnnotation (typeof (TestType)); } - // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 - [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation), ProducedBy = Tool.Trimmer)] + // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 + [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation), ProducedBy = Tool.Trimmer | Tool.NativeAot)] public static void GenericMethodWithAnnotationViaLdftn () { var _ = new Action (GenericMethodWithAnnotation); @@ -744,7 +743,7 @@ static void DynamicallyAccessedMembersAll2 () } // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2111", "GenericWithAnnotatedMethod", "AnnotatedMethod", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2111", "GenericWithAnnotatedMethod", "AnnotatedMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static void LdToken () { // Note that this should warn even though the code looks "Correct" diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs index c3116903d6167b..b793d36af76a0d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs @@ -12,6 +12,7 @@ namespace Mono.Linker.Tests.Cases.Reflection { [ExpectedNoWarnings] + [SkipKeptItemsValidation (By = Tool.NativeAot)] public class TypeHierarchyReflectionWarnings { public static void Main () @@ -236,10 +237,10 @@ class AnnotatedPublicEvents public delegate void MyEventHandler (object sender, int i); [Kept] - // We always keep event methods when an event is kept, so this generates warnings + // ILLink always keeps event methods when an event is kept, so this generates warnings // on the event itself (since an event access is considered to reference the annotated add method), // and on the add method (if it is accessed through reflection). - [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--")] + [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--", ProducedBy = Tool.Trimmer)] public event MyEventHandler RUCEvent { @@ -273,6 +274,7 @@ class AnnotatedInterfaces : RequiredInterface [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] // This should produce a warning: https://github.com/dotnet/linker/issues/2161 + [ExpectedWarning("IL2112", "--RUC on AnnotatedInterfaces.UnusedMethod--", ProducedBy = Tool.NativeAot)] [RequiresUnreferencedCode ("--RUC on AnnotatedInterfaces.UnusedMethod--")] public void RUCMethod () { } } @@ -307,7 +309,7 @@ class DerivedFromAnnotatedPublicParameterlessConstructor : AnnotatedPublicParame [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [ExpectedWarning ("IL2112", "--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--")] - [ExpectedWarning ("IL2112", "--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [RequiresUnreferencedCode ("--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--")] public DerivedFromAnnotatedPublicParameterlessConstructor () { } @@ -618,13 +620,13 @@ public virtual void RUCVirtualMethod () { } [KeptBaseType (typeof (Base))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] [ExpectedWarning ("IL2113", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--")] - // https://github.com/dotnet/linker/issues/2815 - // [ExpectedWarning ("IL2112", "--RUCOnVirtualMethodDerivedAnnotated.Derived.RUCVirtualMethod--")] public class Derived : Base { [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("--RUCOnVirtualMethodDerivedAnnotated.Derived.RUCVirtualMethod--")] + // https://github.com/dotnet/linker/issues/2815 + [ExpectedWarning ("IL2112", "--RUCOnVirtualMethodDerivedAnnotated.Derived.RUCVirtualMethod--", ProducedBy = Tool.NativeAot)] public virtual void RUCVirtualMethod () { } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs index 553ba49e6bb689..f58b051b4a3e96 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs @@ -10,7 +10,6 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] [SkipKeptItemsValidation] [ExpectedNoWarnings] public class ReflectionAccessFromCompilerGeneratedCode @@ -25,8 +24,11 @@ public static void Main () class ReflectionAccessFromStateMachine { [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations), CompilerGeneratedCode = true)] @@ -37,6 +39,8 @@ static IEnumerable TestIterator () } [RequiresUnreferencedCode ("--TestIteratorWithRUC--")] + [RequiresAssemblyFiles ("--TestIteratorWithRUC--")] + [RequiresDynamicCode ("--TestIteratorWithRUC--")] static IEnumerable TestIteratorWithRUC () { typeof (TypeWithMethodWithRequires).RequiresAll (); @@ -44,8 +48,11 @@ static IEnumerable TestIteratorWithRUC () } [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations), CompilerGeneratedCode = true)] @@ -56,6 +63,8 @@ static async void TestAsync () } [RequiresUnreferencedCode ("--TestAsyncWithRUC--")] + [RequiresAssemblyFiles ("--TestAsyncWithRUC--")] + [RequiresDynamicCode ("--TestAsyncWithRUC--")] static async void TestAsyncWithRUC () { typeof (TypeWithMethodWithRequires).RequiresAll (); @@ -63,10 +72,14 @@ static async void TestAsyncWithRUC () } [ExpectedWarning ("IL2026", "--TestIteratorWithRUC--")] + [ExpectedWarning ("IL3002", "--TestIteratorWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--TestIteratorWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] [ExpectedWarning ("IL2026", "--TestAsyncWithRUC--")] + [ExpectedWarning ("IL3002", "--TestAsyncWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--TestAsyncWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] public static void Test () { - TestIterator (); + TestIterator ().GetEnumerator ().MoveNext (); // Must actually une the enumerator, otherwise NativeAOT will trim the implementation TestIteratorWithRUC (); TestAsync (); TestAsyncWithRUC (); @@ -78,8 +91,11 @@ class ReflectionAccessFromLocalFunction static void TestLocalFunction () { [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--")] - [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations))] @@ -91,9 +107,13 @@ void LocalFunction () } [ExpectedWarning ("IL2026", "--LocalFunction--")] + [ExpectedWarning ("IL3002", "--LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] static void TestLocalFunctionWithRUC () { [RequiresUnreferencedCode ("--LocalFunction--")] + [RequiresAssemblyFiles ("--LocalFunction--")] + [RequiresDynamicCode ("--LocalFunction--")] void LocalFunction () { typeof (TypeWithMethodWithRequires).RequiresAll (); @@ -102,6 +122,8 @@ void LocalFunction () } [RequiresUnreferencedCode ("--TestLocalFunctionInMethodWithRUC--")] + [RequiresAssemblyFiles ("--TestLocalFunctionInMethodWithRUC--")] + [RequiresDynamicCode ("--TestLocalFunctionInMethodWithRUC--")] static void TestLocalFunctionInMethodWithRUC () { void LocalFunction () @@ -112,6 +134,8 @@ void LocalFunction () } [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRUC--")] + [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] public static void Test () { TestLocalFunction (); @@ -126,8 +150,11 @@ static void TestLambda () { var lambda = [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--")] - [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations))] @@ -138,10 +165,14 @@ static void TestLambda () } [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRUC--")] + [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] static void TestLambdaWithRUC () { var lambda = [RequiresUnreferencedCode ("--TestLambdaInMethodWithRUC--")] + [RequiresAssemblyFiles ("--TestLambdaInMethodWithRUC--")] + [RequiresDynamicCode ("--TestLambdaInMethodWithRUC--")] () => { typeof (TypeWithMethodWithRequires).RequiresAll (); }; @@ -149,6 +180,8 @@ static void TestLambdaWithRUC () } [RequiresUnreferencedCode ("--TestLambdaInMethodWithRUC--")] + [RequiresAssemblyFiles ("--TestLambdaInMethodWithRUC--")] + [RequiresDynamicCode ("--TestLambdaInMethodWithRUC--")] static void TestLambdaInMethodWithRUC () { var lambda = @@ -159,6 +192,8 @@ static void TestLambdaInMethodWithRUC () } [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRUC--")] + [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] public static void Test () { TestLambda (); @@ -184,9 +219,13 @@ public static void MethodWithRequires () public static void MethodWithAnnotations ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) { } [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--")] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] public static void MethodWithLocalFunctionWithRUC () { [RequiresUnreferencedCode ("--MethodWithLocalFunctionWithRUC.LocalFunction--")] + [RequiresAssemblyFiles ("--MethodWithLocalFunctionWithRUC.LocalFunction--")] + [RequiresDynamicCode ("--MethodWithLocalFunctionWithRUC.LocalFunction--")] void LocalFunction () { } LocalFunction (); @@ -195,12 +234,16 @@ void LocalFunction () public static void MethodWithLocalFunctionCallsRUC () { [ExpectedWarning ("IL2026", "--MethodWithRUC--")] + [ExpectedWarning ("IL3002", "--MethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] void LocalFunction () => MethodWithRUC (); LocalFunction (); } } [RequiresUnreferencedCode ("--MethodWithRUC--")] + [RequiresAssemblyFiles ("--MethodWithRUC--")] + [RequiresDynamicCode ("--MethodWithRUC--")] static void MethodWithRUC () { } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs index 95672d4222c61f..e5b28b192b7639 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs @@ -42,20 +42,11 @@ class RequiresAttributeMismatch [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()")] [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] @@ -65,9 +56,7 @@ class RequiresAttributeMismatch [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()")] [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2026", "IBaseWithRequires.PropertyAnnotationInAccesor.get")] [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs index 8cc523da281a4e..06179031c754bb 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs @@ -196,8 +196,6 @@ static IEnumerable TestMethodParameterWithRequirements (Type unknownType = yield return 0; } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -207,8 +205,6 @@ static IEnumerable TestGenericMethodParameterRequirement () yield return 0; } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -375,8 +371,6 @@ static async void TestMethodParameterWithRequirements (Type unknownType = null) await MethodAsync (); } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -386,8 +380,6 @@ static async void TestGenericMethodParameterRequirement () await MethodAsync (); } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -568,8 +560,6 @@ static async IAsyncEnumerable TestMethodParameterWithRequirements (Type unk yield return 0; } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -580,8 +570,6 @@ static async IAsyncEnumerable TestGenericMethodParameterRequirement unknownType.RequiresNonPublicMethods (); } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -1397,8 +1382,6 @@ static void TestGenericMethodParameterRequirement () }; } - // https://github.com/dotnet/runtime/issues/68688 - // This test passes on NativeAot even without the Requires* attributes. [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] @@ -1950,8 +1933,6 @@ static async void TestAsyncOnlyReferencedViaReflectionWhichShouldWarn () [ExpectedWarning ("IL3002", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] - // ILLink warns about reflection access to compiler-generated state machine members. - // https://github.com/dotnet/runtime/issues/68786 [ExpectedWarning ("IL2118", nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestAsyncOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2118", nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestIteratorOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()", @@ -2082,8 +2063,6 @@ void LocalFunction () [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL3002", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - // ILLink warn about reflection access to compiler-generated code - // https://github.com/dotnet/runtime/issues/68786 [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection), ProducedBy = Tool.Trimmer)] static void TestAll () @@ -2117,8 +2096,6 @@ static void TestAll () [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL3002", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - // ILLink warn about reflection access to compiler-generated code - // https://github.com/dotnet/runtime/issues/68786 [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), "<" + nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection) + ">", ProducedBy = Tool.Trimmer)] static void TestNonPublicMethods () diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index 93445e8c63b59e..2ae2c7fb2002b4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -535,16 +535,16 @@ class ReflectionAccessOnMethod [ExpectedWarning ("IL3050", "BaseWithoutRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2026", "BaseWithoutRequiresOnType.Method()")] [ExpectedWarning ("IL3050", "BaseWithoutRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] - // ILLink skips warnings for base method overrides, assuming it is covered by RUC on the base method. - [ExpectedWarning ("IL2026", "DerivedWithRequiresOnType.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + // https://github.com/dotnet/linker/issues/2533 + [ExpectedWarning ("IL2026", "DerivedWithRequiresOnType.Method()", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method(Int32)")] [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method(Int32)", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method()")] [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method()", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL2026", "ImplementationWithRequiresOnType.Method()")] [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] - // ILLink skips warnings for interface overrides, assuming it is covered by RUC on the interface method. + // https://github.com/dotnet/linker/issues/2533 + // NativeAOT has a correct override resolution and in this case the method is not an override - so it should warn [ExpectedWarning ("IL2026", "ImplementationWithRequiresOnType.Method(Int32)", ProducedBy = Tool.Analyzer | Tool.NativeAot)] [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method(Int32)", ProducedBy = Tool.NativeAot)] // ILLink incorrectly skips warnings for derived method, under the assumption that @@ -552,8 +552,7 @@ class ReflectionAccessOnMethod // is unannotated (and the mismatch produces no warning because the derived // type has RUC). // https://github.com/dotnet/linker/issues/2533 - [ExpectedWarning ("IL2026", "DerivedWithRequiresOnTypeOverBaseWithNoRequires.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnTypeOverBaseWithNoRequires.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "DerivedWithRequiresOnTypeOverBaseWithNoRequires.Method()", ProducedBy = Tool.Analyzer)] static void TestDAMAccess () { // Warns because BaseWithoutRequiresOnType.Method has Requires on the method @@ -784,13 +783,13 @@ class BaseForDAMAnnotatedClass [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] [RequiresUnreferencedCode ("This class is dangerous")] [RequiresDynamicCode ("This class is dangerous")] - [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseField", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseField", ProducedBy = Tool.Trimmer | Tool.NativeAot)] class DAMAnnotatedClass : BaseForDAMAnnotatedClass { - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicField", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicField", ProducedBy = Tool.Trimmer | Tool.NativeAot)] public static int publicField; - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privatefield", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privatefield", ProducedBy = Tool.Trimmer | Tool.NativeAot)] static int privatefield; } @@ -802,7 +801,7 @@ static void TestDAMOnTypeAccess (DAMAnnotatedClass instance) [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] class DAMAnnotatedClassAccessedFromRUCScope { - [ExpectedWarning ("IL2112", "DAMAnnotatedClassAccessedFromRUCScope.RUCMethod", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClassAccessedFromRUCScope.RUCMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [RequiresUnreferencedCode ("--RUCMethod--")] public static void RUCMethod () { } } @@ -1014,21 +1013,21 @@ class BaseForDAMAnnotatedClass [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] [RequiresUnreferencedCode ("This class is dangerous")] [RequiresDynamicCode ("This class is dangerous")] - [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.get", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.set", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] class DAMAnnotatedClass : BaseForDAMAnnotatedClass { public static int publicProperty { - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.get", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] get; - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.set", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] set; } static int privateProperty { - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.get", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] get; - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.set", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] set; } } @@ -1055,7 +1054,7 @@ public class AttributeWithRequires : Attribute // `field` cannot be used as named attribute argument because is static, and if accessed via // a property the property will be the one generating the warning, but then the warning will - // be suppresed by the Requires on the declaring type + // be suppressed by the Requires on the declaring type public int PropertyOnAttribute { get { return field; } set { field = value; } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs index 06294b22d85c2f..79273bd74bb736 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs @@ -12,7 +12,6 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { - [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)] [SkipKeptItemsValidation] [ExpectedNoWarnings] class RequiresOnVirtualsAndInterfaces @@ -51,8 +50,8 @@ public override void VirtualMethodRequires () } [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestBaseTypeVirtualMethodRequires () { var tmp = new BaseType (); @@ -61,8 +60,8 @@ static void TestBaseTypeVirtualMethodRequires () [LogDoesNotContain ("TypeWhichOverridesMethod.VirtualMethodRequires")] [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestTypeWhichOverridesMethodVirtualMethodRequires () { var tmp = new TypeWhichOverridesMethod (); @@ -71,8 +70,8 @@ static void TestTypeWhichOverridesMethodVirtualMethodRequires () [LogDoesNotContain ("TypeWhichOverridesMethod.VirtualMethodRequires")] [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestTypeWhichOverridesMethodVirtualMethodRequiresOnBase () { BaseType tmp = new TypeWhichOverridesMethod (); @@ -101,8 +100,8 @@ public override int VirtualPropertyRequires { [LogDoesNotContain ("TypeWhichOverridesProperty.VirtualPropertyRequires")] [ExpectedWarning ("IL2026", "--PropertyBaseType.VirtualPropertyRequires--")] - [ExpectedWarning ("IL3002", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestTypeWhichOverridesVirtualPropertyRequires () { var tmp = new TypeWhichOverridesProperty (); @@ -111,8 +110,8 @@ static void TestTypeWhichOverridesVirtualPropertyRequires () [LogDoesNotContain ("ImplementationClass.MethodWithRequires")] [ExpectedWarning ("IL2026", "--IRequires.MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestInterfaceMethodWithRequires () { IRequires inst = new ImplementationClass (); @@ -161,8 +160,8 @@ public override DerivedReturnType GetRequires () [LogDoesNotContain ("--CovariantReturnBase.GetRequires--")] [ExpectedWarning ("IL2026", "--CovariantReturnDerived.GetRequires--")] - [ExpectedWarning ("IL3002", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void TestCovariantReturnCallOnDerived () { var tmp = new CovariantReturnDerived (); @@ -190,10 +189,9 @@ public override DerivedReturnType GetRequires () } } - // https://github.com/dotnet/runtime/issues/73321 [ExpectedWarning ("IL2026", "--CovariantReturnViaLdftn.Derived.GetRequires--")] - [ExpectedWarning ("IL3002", "--CovariantReturnViaLdftn.Derived.GetRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--CovariantReturnViaLdftn.Derived.GetRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--CovariantReturnViaLdftn.Derived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--CovariantReturnViaLdftn.Derived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] public static void Test () { var tmp = new Derived (); @@ -221,13 +219,13 @@ public virtual void RUCMethod () { } [ExpectedWarning ("IL2026", "Message for --NewSlotVirtual.Base.RUCMethod--")] // Reflection triggered warnings are not produced by analyzer for RDC/RAS - // [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Base.RUCMethod--", ProducedBy = ProducedBy.Analyzer)] - // [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Base.RUCMethod--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Base.RUCMethod--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Base.RUCMethod--", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/linker/issues/2815 - [ExpectedWarning ("IL2026", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] // Reflection triggered warnings are not produced by analyzer for RDC/RAS - // [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = ProducedBy.Analyzer)] - // [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = Tool.NativeAot)] public static void Test () { typeof (Derived).RequiresPublicMethods (); @@ -260,11 +258,11 @@ public static void AbstractMethod () { } } [ExpectedWarning ("IL2026", "--StaticInterfaces.IRequires.VirtualMethod--")] - [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.VirtualMethod--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.VirtualMethod--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.VirtualMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.VirtualMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] [ExpectedWarning ("IL2026", "--StaticInterfaces.IRequires.AbstractMethod--")] - [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.AbstractMethod--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.AbstractMethod--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.AbstractMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.AbstractMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] static void UseRequiresMethods () where T : IRequires { T.AbstractMethod (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs index f4d768a692b35c..15dd829a93a198 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs @@ -17,9 +17,7 @@ class RequiresViaDataflow { // Base/Derived and Implementation/Interface differs between ILLink and analyzer https://github.com/dotnet/linker/issues/2533 [ExpectedWarning ("IL2026", "--DynamicallyAccessedTypeWithRequires.MethodWithRequires--")] - [ExpectedWarning ("IL2026", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2026", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--")] [ExpectedWarning ("IL3002", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] [ExpectedWarning ("IL3050", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)]