diff options
author | Sven Boemer <sbomer@gmail.com> | 2021-08-10 20:10:20 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-10 20:10:20 +0300 |
commit | d8b94bd244f9239ef394817e2bd9a37ec1bae838 (patch) | |
tree | 0d74ea5c59ba7f18c121b60eb530d4f7a41cc156 | |
parent | e21bb44ca909d33c18acf3ed0b68f94a413351a5 (diff) |
Fix warnings for DAM.All (#2191)
* Fix warnings for DAM.All
Fixes https://github.com/mono/linker/issues/2159
* Add tests
* PR feedback
- Remove unnecessary helper
* Avoid redundant DAM warnings for base members
* PR feedback
- Resolve -> TryResolve
- Avoid nested yield returns
- Testcases with base instantiated over self for generic parameter with
requirements
8 files changed, 379 insertions, 157 deletions
diff --git a/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs b/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs index a176f5e0e..85b597fe1 100644 --- a/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs +++ b/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs @@ -19,13 +19,18 @@ namespace Mono.Linker internal static class DynamicallyAccessedMembersBinder { - // Returns the members of the type bound by memberTypes. For DynamicallyAccessedMemberTypes.All, this returns a single null result. - // This sentinel value allows callers to handle the case where DynamicallyAccessedMemberTypes.All conceptually binds to the entire type - // including all recursive nested members. - public static IEnumerable<IMetadataTokenProvider> GetDynamicallyAccessedMembers (this TypeDefinition typeDefinition, LinkContext context, DynamicallyAccessedMemberTypes memberTypes) + // Returns the members of the type bound by memberTypes. For DynamicallyAccessedMemberTypes.All, this returns all members of the type and its + // nested types, including interface implementations, plus the same or any base types or implemented interfaces. + // DynamicallyAccessedMemberTypes.PublicNestedTypes and NonPublicNestedTypes do the same for members of the selected nested types. + public static IEnumerable<IMetadataTokenProvider> GetDynamicallyAccessedMembers (this TypeDefinition typeDefinition, LinkContext context, DynamicallyAccessedMemberTypes memberTypes, bool declaredOnly = false) { + var declaredOnlyFlags = declaredOnly ? BindingFlags.DeclaredOnly : BindingFlags.Default; + if (memberTypes == DynamicallyAccessedMemberTypes.All) { - yield return null; + var members = new List<IMetadataTokenProvider> (); + typeDefinition.GetAllOnType (context, declaredOnly, members); + foreach (var m in members) + yield return m; yield break; } @@ -45,57 +50,67 @@ namespace Mono.Linker } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicMethods)) { - foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic)) + foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) yield return m; } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicMethods)) { - foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.Public)) + foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags)) yield return m; } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicFields)) { - foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic)) + foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) yield return f; } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicFields)) { - foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.Public)) + foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags)) yield return f; } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)) { - foreach (var t in typeDefinition.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.NonPublic)) - yield return t; + foreach (var nested in typeDefinition.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.NonPublic)) { + yield return nested; + var members = new List<IMetadataTokenProvider> (); + nested.GetAllOnType (context, declaredOnly: false, members); + foreach (var m in members) + yield return m; + } } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicNestedTypes)) { - foreach (var t in typeDefinition.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.Public)) - yield return t; + foreach (var nested in typeDefinition.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.Public)) { + yield return nested; + var members = new List<IMetadataTokenProvider> (); + nested.GetAllOnType (context, declaredOnly: false, members); + foreach (var m in members) + yield return m; + } } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicProperties)) { - foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic)) + foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) yield return p; } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicProperties)) { - foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.Public)) + foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags)) yield return p; } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicEvents)) { - foreach (var e in typeDefinition.GetEventsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic)) + foreach (var e in typeDefinition.GetEventsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) yield return e; } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicEvents)) { - foreach (var e in typeDefinition.GetEventsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.Public)) + foreach (var e in typeDefinition.GetEventsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.Public | declaredOnlyFlags)) yield return e; } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypesOverlay.Interfaces)) { - foreach (var i in typeDefinition.GetAllInterfaceImplementations (context)) + foreach (var i in typeDefinition.GetAllInterfaceImplementations (context, declaredOnly)) yield return i; } } @@ -160,6 +175,9 @@ namespace Mono.Linker yield return method; } + if ((bindingFlags & BindingFlags.DeclaredOnly) == BindingFlags.DeclaredOnly) + yield break; + type = context.TryResolve (type.BaseType); onBaseType = true; } @@ -196,6 +214,9 @@ namespace Mono.Linker yield return field; } + if ((bindingFlags & BindingFlags.DeclaredOnly) == BindingFlags.DeclaredOnly) + yield break; + type = context.TryResolve (type.BaseType); onBaseType = true; } @@ -261,6 +282,9 @@ namespace Mono.Linker yield return property; } + if ((bindingFlags & BindingFlags.DeclaredOnly) == BindingFlags.DeclaredOnly) + yield break; + type = context.TryResolve (type.BaseType); onBaseType = true; } @@ -306,26 +330,84 @@ namespace Mono.Linker yield return @event; } + if ((bindingFlags & BindingFlags.DeclaredOnly) == BindingFlags.DeclaredOnly) + yield break; + type = context.TryResolve (type.BaseType); onBaseType = true; } } - public static IEnumerable<InterfaceImplementation> GetAllInterfaceImplementations (this TypeDefinition type, LinkContext context) + public static IEnumerable<InterfaceImplementation> GetAllInterfaceImplementations (this TypeDefinition type, LinkContext context, bool declaredOnly) { while (type != null) { foreach (var i in type.Interfaces) { yield return i; - TypeDefinition interfaceType = context.TryResolve (i.InterfaceType); - if (interfaceType != null) { - foreach (var innerInterface in interfaceType.GetAllInterfaceImplementations (context)) - yield return innerInterface; + if (!declaredOnly) { + TypeDefinition interfaceType = context.TryResolve (i.InterfaceType); + if (interfaceType != null) { + foreach (var innerInterface in interfaceType.GetAllInterfaceImplementations (context, declaredOnly: false)) + yield return innerInterface; + } } } + if (declaredOnly) + yield break; + type = context.TryResolve (type.BaseType); } } + + public static void GetAllOnType (this TypeDefinition type, LinkContext context, bool declaredOnly, List<IMetadataTokenProvider> members) => GetAllOnType (type, context, declaredOnly, members, new HashSet<TypeDefinition> ()); + + static void GetAllOnType (TypeDefinition type, LinkContext context, bool declaredOnly, List<IMetadataTokenProvider> members, HashSet<TypeDefinition> types) + { + if (!types.Add (type)) + return; + + if (type.HasNestedTypes) { + foreach (var nested in type.NestedTypes) { + members.Add (nested); + // Base types and interfaces of nested types are always included. + GetAllOnType (nested, context, declaredOnly: false, members, types); + } + } + + if (!declaredOnly) { + var baseType = context.TryResolve (type.BaseType); + if (baseType != null) + GetAllOnType (baseType, context, declaredOnly: false, members, types); + } + + if (!declaredOnly && type.HasInterfaces) { + foreach (var iface in type.Interfaces) { + members.Add (iface); + var interfaceType = context.TryResolve (iface.InterfaceType); + GetAllOnType (interfaceType, context, declaredOnly: false, members, types); + } + } + + if (type.HasFields) { + foreach (var f in type.Fields) + members.Add (f); + } + + if (type.HasMethods) { + foreach (var m in type.Methods) + members.Add (m); + } + + if (type.HasProperties) { + foreach (var p in type.Properties) + members.Add (p); + } + + if (type.HasEvents) { + foreach (var e in type.Events) + members.Add (e); + } + } } }
\ No newline at end of file diff --git a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs index a460fb5d2..f367a3f4c 100644 --- a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs @@ -127,7 +127,17 @@ namespace Mono.Linker.Dataflow // Handle cases where a type has no members but annotations are to be applied to derived type members reflectionPatternContext.RecordHandledPattern (); - MarkTypeForDynamicallyAccessedMembers (ref reflectionPatternContext, type, annotation, DependencyKind.DynamicallyAccessedMemberOnType); + // The annotations this type inherited from its base types should not produce + // warnings on the base members, since those are covered by warnings in the base type. + // For now, annotations that are inherited from base types but also declared explicitly on this type + // still warn about base members since the cache doesn't track enough information to tell the difference. + var declaredAnnotation = _context.Annotations.FlowAnnotations.GetTypeAnnotation (type); + var inheritedOnlyAnnotation = annotation & ~declaredAnnotation; + + // Warn about all members accessed by the annotation on this type (including members of base types/interfaces) + MarkTypeForDynamicallyAccessedMembers (ref reflectionPatternContext, type, declaredAnnotation, DependencyKind.DynamicallyAccessedMemberOnType, declaredOnly: false); + // Warn about members accessed by inherited annotations (not including members of base types/interfaces) + MarkTypeForDynamicallyAccessedMembers (ref reflectionPatternContext, type, inheritedOnlyAnnotation, DependencyKind.DynamicallyAccessedMemberOnType, declaredOnly: true); } ValueNode GetValueNodeForCustomAttributeArgument (CustomAttributeArgument argument) @@ -2285,9 +2295,9 @@ namespace Mono.Linker.Dataflow static bool HasBindingFlag (BindingFlags? bindingFlags, BindingFlags? search) => bindingFlags != null && (bindingFlags & search) == search; - void MarkTypeForDynamicallyAccessedMembers (ref ReflectionPatternContext reflectionContext, TypeDefinition typeDefinition, DynamicallyAccessedMemberTypes requiredMemberTypes, DependencyKind dependencyKind) + void MarkTypeForDynamicallyAccessedMembers (ref ReflectionPatternContext reflectionContext, TypeDefinition typeDefinition, DynamicallyAccessedMemberTypes requiredMemberTypes, DependencyKind dependencyKind, bool declaredOnly = false) { - foreach (var member in typeDefinition.GetDynamicallyAccessedMembers (_context, requiredMemberTypes)) { + foreach (var member in typeDefinition.GetDynamicallyAccessedMembers (_context, requiredMemberTypes, declaredOnly)) { switch (member) { case MethodDefinition method: MarkMethod (ref reflectionContext, method, dependencyKind); @@ -2296,8 +2306,7 @@ namespace Mono.Linker.Dataflow MarkField (ref reflectionContext, field, dependencyKind); break; case TypeDefinition nestedType: - DependencyInfo nestedDependencyInfo = new DependencyInfo (dependencyKind, reflectionContext.Source); - reflectionContext.RecordRecognizedPattern (nestedType, () => _markStep.MarkEntireType (nestedType, includeBaseAndInterfaceTypes: true, nestedDependencyInfo)); + MarkType (ref reflectionContext, nestedType, dependencyKind); break; case PropertyDefinition property: MarkProperty (ref reflectionContext, property, dependencyKind); @@ -2308,10 +2317,6 @@ namespace Mono.Linker.Dataflow case InterfaceImplementation interfaceImplementation: MarkInterfaceImplementation (ref reflectionContext, interfaceImplementation, dependencyKind); break; - case null: - DependencyInfo dependencyInfo = new DependencyInfo (dependencyKind, reflectionContext.Source); - reflectionContext.RecordRecognizedPattern (typeDefinition, () => _markStep.MarkEntireType (typeDefinition, includeBaseAndInterfaceTypes: true, dependencyInfo)); - break; } } } diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs index afdde1402..792676e69 100644 --- a/src/linker/Linker.Steps/MarkStep.cs +++ b/src/linker/Linker.Steps/MarkStep.cs @@ -59,7 +59,7 @@ namespace Mono.Linker.Steps readonly List<(TypeDefinition Type, MethodBody Body, Instruction Instr)> _pending_isinst_instr; UnreachableBlocksOptimizer _unreachableBlocksOptimizer; MarkStepContext _markContext; - readonly Dictionary<TypeDefinition, bool> _entireTypesMarked; // The value is markBaseAndInterfaceTypes flag used to mark the type + readonly HashSet<TypeDefinition> _entireTypesMarked; DynamicallyAccessedMembersTypeHierarchy _dynamicallyAccessedMembersTypeHierarchy; MarkScopeStack _scopeStack; @@ -71,9 +71,7 @@ namespace Mono.Linker.Steps static readonly DependencyKind[] _entireTypeReasons = new DependencyKind[] { DependencyKind.AccessedViaReflection, DependencyKind.BaseType, - DependencyKind.DynamicallyAccessedMember, - DependencyKind.DynamicallyAccessedMemberOnType, - DependencyKind.DynamicDependency, + DependencyKind.PreservedDependency, DependencyKind.NestedType, DependencyKind.TypeInAssembly, DependencyKind.Unspecified, @@ -196,7 +194,7 @@ namespace Mono.Linker.Steps _dynamicInterfaceCastableImplementationTypes = new List<TypeDefinition> (); _unreachableBodies = new List<(MethodBody, MarkScopeStack.Scope)> (); _pending_isinst_instr = new List<(TypeDefinition, MethodBody, Instruction)> (); - _entireTypesMarked = new Dictionary<TypeDefinition, bool> (); + _entireTypesMarked = new HashSet<TypeDefinition> (); } public AnnotationStore Annotations => _context.Annotations; @@ -311,77 +309,58 @@ namespace Mono.Linker.Steps return false; } - internal void MarkEntireType (TypeDefinition type, bool includeBaseAndInterfaceTypes, in DependencyInfo reason) - { - // Prevent cases where there's nothing on the stack (can happen when marking entire assemblies) - // In which case we would generate warnings with no source (hard to debug) - using var _ = _scopeStack.CurrentScope.Origin.MemberDefinition == null ? _scopeStack.PushScope (new MessageOrigin (type)) : null; - - MarkEntireTypeInternal (type, includeBaseAndInterfaceTypes, reason); - } - - void MarkEntireTypeInternal (TypeDefinition type, bool includeBaseAndInterfaceTypes, in DependencyInfo reason) + internal void MarkEntireType (TypeDefinition type, in DependencyInfo reason) { #if DEBUG if (!_entireTypeReasons.Contains (reason.Kind)) throw new InternalErrorException ($"Unsupported type dependency '{reason.Kind}'."); #endif - if (_entireTypesMarked.TryGetValue (type, out bool alreadyIncludedBaseAndInterfaceTypes) && - (!includeBaseAndInterfaceTypes || alreadyIncludedBaseAndInterfaceTypes)) - return; - - _entireTypesMarked[type] = includeBaseAndInterfaceTypes; + // Prevent cases where there's nothing on the stack (can happen when marking entire assemblies) + // In which case we would generate warnings with no source (hard to debug) + using var _ = _scopeStack.CurrentScope.Origin.MemberDefinition == null ? _scopeStack.PushScope (new MessageOrigin (type)) : null; - bool isDynamicDependencyReason = reason.Kind == DependencyKind.DynamicallyAccessedMember || reason.Kind == DependencyKind.DynamicDependency || reason.Kind == DependencyKind.DynamicallyAccessedMemberOnType; + if (!_entireTypesMarked.Add (type)) + return; if (type.HasNestedTypes) { foreach (TypeDefinition nested in type.NestedTypes) - MarkEntireTypeInternal (nested, includeBaseAndInterfaceTypes, new DependencyInfo (isDynamicDependencyReason ? reason.Kind : DependencyKind.NestedType, type)); + MarkEntireType (nested, new DependencyInfo (DependencyKind.NestedType, type)); } Annotations.Mark (type, reason); - var baseTypeDefinition = _context.Resolve (type.BaseType); - if (includeBaseAndInterfaceTypes && baseTypeDefinition != null) { - MarkEntireTypeInternal (baseTypeDefinition, true, new DependencyInfo (isDynamicDependencyReason ? reason.Kind : DependencyKind.BaseType, type)); - } - MarkCustomAttributes (type, new DependencyInfo (isDynamicDependencyReason ? reason.Kind : DependencyKind.CustomAttribute, type)); + MarkCustomAttributes (type, new DependencyInfo (DependencyKind.CustomAttribute, type)); MarkTypeSpecialCustomAttributes (type); if (type.HasInterfaces) { - foreach (InterfaceImplementation iface in type.Interfaces) { - var interfaceTypeDefinition = _context.Resolve (iface.InterfaceType); - if (includeBaseAndInterfaceTypes && interfaceTypeDefinition != null) - MarkEntireTypeInternal (interfaceTypeDefinition, true, new DependencyInfo (reason.Kind, type)); - + foreach (InterfaceImplementation iface in type.Interfaces) MarkInterfaceImplementation (iface, new MessageOrigin (type)); - } } MarkGenericParameterProvider (type); if (type.HasFields) { foreach (FieldDefinition field in type.Fields) { - MarkField (field, new DependencyInfo (isDynamicDependencyReason ? reason.Kind : DependencyKind.MemberOfType, type)); + MarkField (field, new DependencyInfo (DependencyKind.MemberOfType, type)); } } if (type.HasMethods) { foreach (MethodDefinition method in type.Methods) { Annotations.SetAction (method, MethodAction.ForceParse); - MarkMethod (method, new DependencyInfo (isDynamicDependencyReason ? reason.Kind : DependencyKind.MemberOfType, type)); + MarkMethod (method, new DependencyInfo (DependencyKind.MemberOfType, type)); } } if (type.HasProperties) { foreach (var property in type.Properties) { - MarkProperty (property, new DependencyInfo (isDynamicDependencyReason ? reason.Kind : DependencyKind.MemberOfType, type)); + MarkProperty (property, new DependencyInfo (DependencyKind.MemberOfType, type)); } } if (type.HasEvents) { foreach (var ev in type.Events) { - MarkEvent (ev, new DependencyInfo (isDynamicDependencyReason ? reason.Kind : DependencyKind.MemberOfType, type)); + MarkEvent (ev, new DependencyInfo (DependencyKind.MemberOfType, type)); } } } @@ -944,10 +923,10 @@ namespace Mono.Linker.Steps } } - MarkMembersVisibleToReflection (type, members, new DependencyInfo (DependencyKind.DynamicDependency, dynamicDependency.OriginalAttribute)); + MarkMembersVisibleToReflection (members, new DependencyInfo (DependencyKind.DynamicDependency, dynamicDependency.OriginalAttribute)); } - void MarkMembersVisibleToReflection (TypeDefinition typeDefinition, IEnumerable<IMetadataTokenProvider> members, in DependencyInfo reason) + void MarkMembersVisibleToReflection (IEnumerable<IMetadataTokenProvider> members, in DependencyInfo reason) { foreach (var member in members) { switch (member) { @@ -969,9 +948,6 @@ namespace Mono.Linker.Steps case InterfaceImplementation interfaceType: MarkInterfaceImplementation (interfaceType, null, reason); break; - case null: - MarkEntireType (typeDefinition, includeBaseAndInterfaceTypes: true, reason); - break; } } } @@ -1033,7 +1009,7 @@ namespace Mono.Linker.Steps } if (member == "*") { - MarkEntireType (td, includeBaseAndInterfaceTypes: false, new DependencyInfo (DependencyKind.PreservedDependency, ca)); + MarkEntireType (td, new DependencyInfo (DependencyKind.PreservedDependency, ca)); return; } @@ -1411,7 +1387,7 @@ namespace Mono.Linker.Steps MarkCustomAttributes (module, new DependencyInfo (DependencyKind.AssemblyOrModuleAttribute, module)); foreach (TypeDefinition type in module.Types) - MarkEntireType (type, includeBaseAndInterfaceTypes: false, new DependencyInfo (DependencyKind.TypeInAssembly, assembly)); + MarkEntireType (type, new DependencyInfo (DependencyKind.TypeInAssembly, assembly)); foreach (ExportedType exportedType in module.ExportedTypes) { MarkingHelpers.MarkExportedType (exportedType, module, new DependencyInfo (DependencyKind.ExportedType, assembly)); diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs b/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs index f94b9a458..4b626431f 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs @@ -84,6 +84,38 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (AnnotatedField).RequiresPublicFields (); } + class NestedType + { + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public static Type _annotatedField; + } + + [ExpectedWarning ("IL2110", nameof (_annotatedField))] + [ExpectedWarning ("IL2026", "test")] + static void DynamicallyAccessedMembersAll1 () + { + typeof (AnnotatedField).RequiresAll (); + } + + [ExpectedWarning ("IL2110", nameof (_annotatedField))] + [ExpectedWarning ("IL2026", "test")] + static void DynamicallyAccessedMembersAll2 () + { + typeof (AnnotatedField).RequiresAll (); + } + + [ExpectedWarning ("IL2110", nameof (NestedType), nameof (NestedType._annotatedField))] + static void DynamicallyAccessedMembersNestedTypes1 () + { + typeof (AnnotatedField).RequiresNonPublicNestedTypes (); + } + + [ExpectedWarning ("IL2110", nameof (NestedType), nameof (NestedType._annotatedField))] + static void DynamicallyAccessedMembersNestedTypes2 () + { + typeof (AnnotatedField).RequiresNonPublicNestedTypes (); + } + [UnconditionalSuppressMessage ("test", "IL2026")] public static void Test () { @@ -95,6 +127,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow DynamicDependencyByName (); DynamicallyAccessedMembers (); DynamicallyAccessedMembersSuppressedByRUC (); + DynamicallyAccessedMembersAll1 (); + DynamicallyAccessedMembersAll2 (); + DynamicallyAccessedMembersNestedTypes1 (); + DynamicallyAccessedMembersNestedTypes2 (); } } @@ -177,6 +213,22 @@ namespace Mono.Linker.Tests.Cases.DataFlow var _ = new Action<Type> (instance.AnnotatedMethod); } + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))] + [ExpectedWarning ("IL2026", "test")] + [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))] + static void DynamicallyAccessedMembersAll1 () + { + typeof (AnnotatedMethodParameters).RequiresAll (); + } + + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))] + [ExpectedWarning ("IL2026", "test")] + [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))] + static void DynamicallyAccessedMembersAll2 () + { + typeof (AnnotatedMethodParameters).RequiresAll (); + } + [UnconditionalSuppressMessage ("test", "IL2026")] public static void Test () { @@ -189,6 +241,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow DynamicallyAccessedMembersSuppressedByRUC (); Ldftn (); Ldvirtftn (); + DynamicallyAccessedMembersAll1 (); + DynamicallyAccessedMembersAll2 (); } } @@ -395,6 +449,24 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (AnnotatedProperty).RequiresPublicProperties (); } + [ExpectedWarning ("IL2111", nameof (PropertyWithAnnotation) + ".set")] + [ExpectedWarning ("IL2026", "test")] + [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")] + [UnconditionalSuppressMessage ("Test", "IL2110", Justification = "Suppress warning about backing field of PropertyWithAnnotation")] + static void DynamicallyAccessedMembersAll1 () + { + typeof (AnnotatedProperty).RequiresAll (); + } + + [ExpectedWarning ("IL2111", nameof (PropertyWithAnnotation) + ".set")] + [ExpectedWarning ("IL2026", "test")] + [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")] + [UnconditionalSuppressMessage ("Test", "IL2110", Justification = "Suppress warning about backing field of PropertyWithAnnotation")] + static void DynamicallyAccessedMembersAll2 () + { + typeof (AnnotatedProperty).RequiresAll (); + } + [UnconditionalSuppressMessage ("test", "IL2026")] public static void Test () { @@ -410,6 +482,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow DynamicDependencySuppressedByRUC (); DynamicallyAccessedMembers (); DynamicallyAccessedMembersSuppressedByRUC (); + DynamicallyAccessedMembersAll1 (); + DynamicallyAccessedMembersAll2 (); } } @@ -446,12 +520,19 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (AnnotatedGenerics).GetMethod (nameof (GenericWithAnnotation)).MakeGenericMethod (type); } + // Like above, no warning expected + static void DynamicallyAccessedMembersAll () + { + typeof (AnnotatedGenerics).RequiresAll (); + } + public static void Test () { ReflectionOnly (); DynamicDependency (); DynamicallyAccessedMembers (); InstantiateGeneric (); + DynamicallyAccessedMembersAll (); } } @@ -499,6 +580,20 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (AnnotationOnGenerics).RequiresPublicMethods (); } + [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation))] + [ExpectedWarning ("IL2111", "GenericWithAnnotatedMethod", "AnnotatedMethod")] + static void DynamicallyAccessedMembersAll1 () + { + typeof (AnnotationOnGenerics).RequiresAll (); + } + + [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation))] + [ExpectedWarning ("IL2111", "GenericWithAnnotatedMethod", "AnnotatedMethod")] + static void DynamicallyAccessedMembersAll2 () + { + typeof (AnnotationOnGenerics).RequiresAll (); + } + public static void Test () { GenericTypeWithStaticMethodViaLdftn (); @@ -506,6 +601,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow GenericMethodWithAnnotationDirectCall (); GenericMethodWithAnnotationViaLdftn (); GenericMethodDynamicallyAccessedMembers (); + DynamicallyAccessedMembersAll1 (); + DynamicallyAccessedMembersAll2 (); } } diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs index 09de0a015..1665c1abd 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs @@ -243,6 +243,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow static void TestBaseTypeGenericRequirements () { new DerivedTypeWithInstantiatedGenericOnBase (); + new DerivedTypeWithInstantiationOverSelfOnBase (); new DerivedTypeWithOpenGenericOnBase<TestType> (); new DerivedTypeWithOpenGenericOnBaseWithRequirements<TestType> (); } @@ -261,6 +262,15 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } + class GenericBaseTypeWithRequiresAll<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] T> + { + } + + [RecognizedReflectionAccessPattern] + class DerivedTypeWithInstantiationOverSelfOnBase : GenericBaseTypeWithRequirements<DerivedTypeWithInstantiationOverSelfOnBase> + { + } + [UnrecognizedReflectionAccessPattern (typeof (GenericBaseTypeWithRequirements<>), "T", messageCode: "IL2091")] class DerivedTypeWithOpenGenericOnBase<T> : GenericBaseTypeWithRequirements<T> { @@ -277,6 +287,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow static void TestInterfaceTypeGenericRequirements () { IGenericInterfaceTypeWithRequirements<TestType> instance = new InterfaceImplementationTypeWithInstantiatedGenericOnBase (); + new InterfaceImplementationTypeWithInstantiationOverSelfOnBase (); new InterfaceImplementationTypeWithOpenGenericOnBase<TestType> (); new InterfaceImplementationTypeWithOpenGenericOnBaseWithRequirements<TestType> (); } @@ -290,6 +301,15 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } + interface IGenericInterfaceTypeWithRequiresAll<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] T> + { + } + + [RecognizedReflectionAccessPattern] + class InterfaceImplementationTypeWithInstantiationOverSelfOnBase : IGenericInterfaceTypeWithRequiresAll<InterfaceImplementationTypeWithInstantiationOverSelfOnBase> + { + } + [UnrecognizedReflectionAccessPattern (typeof (IGenericInterfaceTypeWithRequirements<>), "T", messageCode: "IL2091")] class InterfaceImplementationTypeWithOpenGenericOnBase<T> : IGenericInterfaceTypeWithRequirements<T> { diff --git a/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMemberTypes.cs b/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMemberTypes.cs index f4bfca071..5ba9d6c25 100644 --- a/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMemberTypes.cs +++ b/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMemberTypes.cs @@ -119,12 +119,17 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies class TypeWithPublicNestedType { [Kept] + [KeptMember (".ctor()")] public class PublicNestedType { + [Kept] public void Method () { } + [Kept] public int field; - + [Kept] void NonPublicMethod () { } + [Kept] + static class EmptyInnerNestedType { } } public void Method () { } @@ -139,6 +144,8 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies [KeptBaseType (typeof (MulticastDelegate))] [KeptMember (".ctor(System.Object,System.IntPtr)")] [KeptMember ("Invoke()")] + [KeptMember ("BeginInvoke(System.AsyncCallback,System.Object)")] + [KeptMember ("EndInvoke(System.IAsyncResult)")] public delegate int PublicDelegate (); private delegate int PrivateDelegate (); @@ -148,12 +155,16 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies class TypeWithNonPublicNestedType { [Kept] + [KeptMember (".ctor()")] class NonPublicNestedType { + [Kept] public void Method () { } + [Kept] public int field; + [Kept] void NonPublicMethod () { } } @@ -171,6 +182,8 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies [KeptBaseType (typeof (MulticastDelegate))] [KeptMember (".ctor(System.Object,System.IntPtr)")] [KeptMember ("Invoke()")] + [KeptMember ("BeginInvoke(System.AsyncCallback,System.Object)")] + [KeptMember ("EndInvoke(System.IAsyncResult)")] private delegate int PrivateDelegate (); } diff --git a/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs b/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs index 3cbdf4b0e..5bd06a7e7 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs @@ -17,20 +17,27 @@ namespace Mono.Linker.Tests.Cases.Reflection { public static void Main () { - RequirePublicMethods (annotatedBase.GetType ()); + annotatedBase.GetType ().RequiresPublicMethods (); + var baseType = annotatedBaseSharedByNestedTypes.GetType (); + baseType.RequiresPublicNestedTypes (); + baseType.RequiresPublicMethods (); + var derivedType = typeof (DerivedWithNestedTypes); // Reference to the derived type should apply base annotations - var t = typeof (DerivedFromAnnotatedBase); - RequirePublicMethods (annotatedDerivedFromBase.GetType ()); - RequirePublicNestedTypes (annotatedPublicNestedTypes.GetType ()); - RequirePublicFields (derivedFromAnnotatedDerivedFromBase.GetType ()); - RequirePublicMethods (annotatedPublicMethods.GetType ()); - RequirePublicFields (annotatedPublicFields.GetType ()); - RequirePublicProperties (annotatedPublicProperties.GetType ()); - RequirePublicEvents (annotatedPublicEvents.GetType ()); - RequirePublicNestedTypes (annotatedPublicNestedTypes.GetType ()); - RequireInterfaces (annotatedInterfaces.GetType ()); - RequireAll (annotatedAll.GetType ()); - RequirePublicMethods (annotatedRUCPublicMethods.GetType ()); + var t1 = typeof (DerivedFromAnnotatedBase); + var t2 = typeof (AnnotatedDerivedFromAnnotatedBase); + annotatedDerivedFromBase.GetType ().RequiresPublicMethods (); + annotatedPublicNestedTypes.GetType ().RequiresPublicNestedTypes (); + derivedFromAnnotatedDerivedFromBase.GetType ().RequiresPublicFields (); + annotatedPublicMethods.GetType ().RequiresPublicMethods (); + annotatedPublicFields.GetType ().RequiresPublicFields (); + annotatedPublicProperties.GetType ().RequiresPublicProperties (); + annotatedPublicEvents.GetType ().RequiresPublicEvents (); + annotatedPublicNestedTypes.GetType ().RequiresPublicNestedTypes (); + annotatedInterfaces.GetType ().RequiresInterfaces (); + annotatedAll.GetType ().RequiresAll (); + var t3 = typeof (DerivedFromAnnotatedAll1); + var t4 = typeof (DerivedFromAnnotatedAll2); + annotatedRUCPublicMethods.GetType ().RequiresPublicMethods (); // Instantiate this type just so its property getters are considered reachable var b = new DerivedFromAnnotatedDerivedFromBase (); @@ -55,6 +62,8 @@ namespace Mono.Linker.Tests.Cases.Reflection [Kept] static AnnotatedBase annotatedBase; [Kept] + static AnnotatedBaseSharedByNestedTypes annotatedBaseSharedByNestedTypes; + [Kept] static AnnotatedDerivedFromBase annotatedDerivedFromBase; [Kept] static AnnotatedPublicNestedTypes annotatedPublicNestedTypes; @@ -92,6 +101,20 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] + [KeptMember (".ctor()")] + [KeptBaseType (typeof (AnnotatedAll))] + class DerivedFromAnnotatedAll1 : AnnotatedAll + { + } + + [Kept] + [KeptMember (".ctor()")] + [KeptBaseType (typeof (AnnotatedAll))] + class DerivedFromAnnotatedAll2 : AnnotatedAll + { + } + + [Kept] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] class AnnotatedPublicMethods @@ -236,11 +259,14 @@ namespace Mono.Linker.Tests.Cases.Reflection [ExpectedWarning ("IL2112", "--RUC on AnnotatedBase--")] [RequiresUnreferencedCode ("--RUC on AnnotatedBase--")] public void RUCMethod () { } + + [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] + public string DAMField1; } [KeptBaseType (typeof (AnnotatedBase))] - // Warning about base member could go away with https://github.com/mono/linker/issues/2175 - [ExpectedWarning ("IL2113", "--RUC on AnnotatedBase--")] class DerivedFromAnnotatedBase : AnnotatedBase { [Kept] @@ -250,6 +276,29 @@ namespace Mono.Linker.Tests.Cases.Reflection public void RUCMethod () { } } + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [KeptBaseType (typeof (AnnotatedBase))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] + // In theory we could avoid warning for public methods on base types because that + // annotation is already inherited from the base type, but currently we warn on base + // members whenever a type has an explicit annotation. + [ExpectedWarning ("IL2113", nameof (AnnotatedBase), nameof (AnnotatedBase.RUCMethod))] + [ExpectedWarning ("IL2115", nameof (AnnotatedBase), nameof (AnnotatedBase.DAMField1))] + class AnnotatedDerivedFromAnnotatedBase : AnnotatedBase + { + [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [ExpectedWarning ("IL2112", "--RUC on AnnotatedDerivedFromAnnotatedBase--")] + [RequiresUnreferencedCode ("--RUC on AnnotatedDerivedFromAnnotatedBase--")] + public void DerivedRUCMethod () { } + + [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [ExpectedWarning ("IL2114", nameof (AnnotatedDerivedFromAnnotatedBase), nameof (DAMField2))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] + public string DAMField2; + } + [KeptMember (".ctor()")] class Base { @@ -314,13 +363,11 @@ namespace Mono.Linker.Tests.Cases.Reflection [KeptMember (".ctor()")] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] - // Warnings about base members could go away with https://github.com/mono/linker/issues/2175 + // The annotation from this type should warn about all public fields including those + // from base types, but the inherited PublicMethods annotation should not warn + // again about base methods. [ExpectedWarning ("IL2115", nameof (Base), nameof (DAMField1))] [ExpectedWarning ("IL2115", nameof (AnnotatedDerivedFromBase), nameof (DAMField2))] - [ExpectedWarning ("IL2113", "--RUCBaseMethod--")] - [ExpectedWarning ("IL2113", "--Base.RUCVirtualMethod--")] - [ExpectedWarning ("IL2113", "--RUC on AnnotatedDerivedFromBase--")] - [ExpectedWarning ("IL2115", nameof (Base), nameof (Base.DAMVirtualProperty) + ".get")] class DerivedFromAnnotatedDerivedFromBase : AnnotatedDerivedFromBase { [Kept] @@ -349,8 +396,19 @@ namespace Mono.Linker.Tests.Cases.Reflection public override string DAMVirtualProperty { [Kept] get; } } + [KeptMember (".ctor()")] + public class BaseTypeOfNestedType + { + [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode ("--RUC on BaseTypeOfNestedType.RUCMethod--")] + public void RUCMethod () { } + } + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] + // Warnings about base types of nested types are shown at the (outer) type level. + [ExpectedWarning ("IL2113", nameof (BaseTypeOfNestedType), nameof (BaseTypeOfNestedType.RUCMethod))] class AnnotatedPublicNestedTypes { [KeptMember (".ctor()")] @@ -364,6 +422,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [KeptMember (".ctor()")] + [KeptBaseType (typeof (BaseTypeOfNestedType))] + public class NestedTypeWithBase : BaseTypeOfNestedType + { + } + + [KeptMember (".ctor()")] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] public class NestedAnnotatedType @@ -407,6 +471,31 @@ namespace Mono.Linker.Tests.Cases.Reflection } } + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes)] + class AnnotatedBaseSharedByNestedTypes + { + [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [ExpectedWarning ("IL2112", "--RUC on AnnotatedBaseSharedByNestedTypes.RUCMethod--")] + [RequiresUnreferencedCode ("--RUC on AnnotatedBaseSharedByNestedTypes.RUCMethod--")] + public void RUCMethod () { } + } + + [KeptBaseType (typeof (AnnotatedBaseSharedByNestedTypes))] + // Nested types that share the outer class base type can produce warnings about base methods of the annotated type. + [ExpectedWarning ("IL2113", "--RUC on AnnotatedBaseSharedByNestedTypes.RUCMethod--")] + class DerivedWithNestedTypes : AnnotatedBaseSharedByNestedTypes + { + + [KeptMember (".ctor()")] + [KeptBaseType (typeof (AnnotatedBaseSharedByNestedTypes))] + public class NestedType : AnnotatedBaseSharedByNestedTypes + { + } + } + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] @@ -428,54 +517,5 @@ namespace Mono.Linker.Tests.Cases.Reflection [ExpectedWarning ("IL2112", "--AnnotatedRUCPublicMethods--")] public static void StaticMethod () { } } - - [Kept] - static void RequirePublicMethods ( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - Type type) - { } - - [Kept] - static void RequirePublicFields ( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] - Type type) - { } - - [Kept] - static void RequirePublicProperties ( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] - Type type) - { } - - [Kept] - static void RequirePublicEvents ( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] - Type type) - { } - - [Kept] - static void RequireAll ( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] - Type type) - { } - - [Kept] - static void RequirePublicNestedTypes ( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] - Type type) - { } - - [Kept] - static void RequireInterfaces ( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] - Type type) - { } } } diff --git a/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs b/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs index fe9a44c3b..7318f1faf 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs @@ -79,7 +79,6 @@ namespace Mono.Linker.Tests.Cases.Reflection [Kept] [KeptBaseType (typeof (Unsuppressed))] - [ExpectedWarning ("IL2113", "--RUC on Unsuppressed--")] class DerivedFromUnsuppressed1 : Unsuppressed { [Kept] @@ -91,7 +90,6 @@ namespace Mono.Linker.Tests.Cases.Reflection [Kept] [KeptBaseType (typeof (Unsuppressed))] - [ExpectedWarning ("IL2113", "--RUC on Unsuppressed--")] class DerivedFromUnsuppressed2 : Unsuppressed { [Kept] @@ -116,8 +114,6 @@ namespace Mono.Linker.Tests.Cases.Reflection [Kept] [KeptBaseType (typeof (Suppressed))] - // Base method should warn even though it was suppressed on the base - [ExpectedWarning ("IL2113", "--RUC on Suppressed--")] class DerivedFromSuppressed1 : Suppressed { [Kept] @@ -129,8 +125,6 @@ namespace Mono.Linker.Tests.Cases.Reflection [Kept] [KeptBaseType (typeof (Suppressed))] - // Base method should warn even though it was suppressed on the base - [ExpectedWarning ("IL2113", "--RUC on Suppressed--")] class DerivedFromSuppressed2 : Suppressed { [Kept] @@ -142,7 +136,6 @@ namespace Mono.Linker.Tests.Cases.Reflection [Kept] [KeptBaseType (typeof (Unsuppressed))] - [ExpectedWarning ("IL2113", "--RUC on Unsuppressed--")] class SuppressedOnDerived1 : Unsuppressed { [Kept] @@ -155,7 +148,6 @@ namespace Mono.Linker.Tests.Cases.Reflection [Kept] [KeptBaseType (typeof (Unsuppressed))] - [ExpectedWarning ("IL2113", "--RUC on Unsuppressed--")] class SuppressedOnDerived2 : Unsuppressed { [Kept] @@ -168,9 +160,6 @@ namespace Mono.Linker.Tests.Cases.Reflection [Kept] [KeptBaseType (typeof (Unsuppressed))] - [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))] - // Suppress warnings about base members - [UnconditionalSuppressMessage ("TrimAnalysis", "IL2113")] class SuppressedBaseWarningsOnDerived : Unsuppressed { [Kept] |