Add tests for RUC warnings on override methods (#86015)
authorVitek Karas <10670590+vitek-karas@users.noreply.github.com>
Fri, 12 May 2023 20:31:25 +0000 (13:31 -0700)
committerGitHub <noreply@github.com>
Fri, 12 May 2023 20:31:25 +0000 (13:31 -0700)
These are tests for bug https://github.com/dotnet/runtime/issues/86008.

I also restructured the test file into nested classes some more as it's easier to navigate this way.

Also adds a test for https://github.com/dotnet/runtime/issues/86032.

src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAccessedThrough.cs
src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs

index c345c9c..15c0993 100644 (file)
@@ -22,6 +22,7 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability
                {
                        TestRequiresOnlyThroughReflection ();
                        AccessedThroughReflectionOnGenericType<TestType>.Test ();
+                       AccessedThroughGenericParameterAnnotation.Test ();
                        AccessThroughSpecialAttribute.Test ();
                        AccessThroughPInvoke.Test ();
                        AccessThroughNewConstraint.Test<TestType> ();
@@ -73,6 +74,59 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability
                        }
                }
 
+               class AccessedThroughGenericParameterAnnotation
+               {
+                       class TypeWithRequiresMethod
+                       {
+                               [RequiresUnreferencedCode("--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--")]
+                               [RequiresDynamicCode ("--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--")]
+                               [RequiresAssemblyFiles ("--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--")]
+                               public static void MethodWhichRequires () { }
+                       }
+
+                       class TypeWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T>
+                       {
+                               public TypeWithPublicMethods () { }
+                       }
+
+                       [ExpectedWarning ("IL2026", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--")]
+                       [ExpectedWarning ("IL3002", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)]
+                       static void TestAccessOnGenericType ()
+                       {
+                               new TypeWithPublicMethods<TypeWithRequiresMethod> ();
+                       }
+
+                       static void MethodWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { }
+
+                       [ExpectedWarning ("IL2026", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--")]
+                       [ExpectedWarning ("IL3002", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)]
+                       static void TestAccessOnGenericMethod ()
+                       {
+                               MethodWithPublicMethods<TypeWithRequiresMethod> ();
+                       }
+
+                       static void MethodWithPublicMethodsInference<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> (T instance) { }
+
+                       // https://github.com/dotnet/runtime/issues/86032
+                       // IL2026 should be produced by the analyzer as well, but it has a bug around inferred generic arguments
+                       [ExpectedWarning ("IL2026", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)]
+                       [ExpectedWarning ("IL3002", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)]
+                       static void TestAccessOnGenericMethodWithInferenceOnMethod ()
+                       {
+                               MethodWithPublicMethodsInference (new TypeWithRequiresMethod ());
+                       }
+
+                       public static void Test ()
+                       {
+                               TestAccessOnGenericType ();
+                               TestAccessOnGenericMethod ();
+                               TestAccessOnGenericMethodWithInferenceOnMethod ();
+                       }
+               }
+
                class AccessThroughSpecialAttribute
                {
                        // https://github.com/dotnet/linker/issues/1873
index 79273bd..5470aa1 100644 (file)
@@ -18,154 +18,250 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability
        {
                public static void Main ()
                {
-                       TestBaseTypeVirtualMethodRequires ();
-                       TestTypeWhichOverridesMethodVirtualMethodRequires ();
-                       TestTypeWhichOverridesMethodVirtualMethodRequiresOnBase ();
-                       TestTypeWhichOverridesVirtualPropertyRequires ();
-                       TestInterfaceMethodWithRequires ();
-                       TestCovariantReturnCallOnDerived ();
+                       VirtualMethod.Test ();
+                       VirtualProperty.Test ();
+                       InterfaceMethod.Test ();
+                       CovariantReturn.Test ();
                        CovariantReturnViaLdftn.Test ();
                        NewSlotVirtual.Test ();
                        StaticInterfaces.Test ();
                }
 
-               class BaseType
+               class VirtualMethod
                {
-                       [RequiresUnreferencedCode ("Message for --BaseType.VirtualMethodRequires--")]
-                       [RequiresAssemblyFiles ("Message for --BaseType.VirtualMethodRequires--")]
-                       [RequiresDynamicCode ("Message for --BaseType.VirtualMethodRequires--")]
-                       public virtual void VirtualMethodRequires ()
+                       class BaseType
                        {
+                               [RequiresUnreferencedCode ("Message for --BaseType.VirtualMethodRequires--")]
+                               [RequiresAssemblyFiles ("Message for --BaseType.VirtualMethodRequires--")]
+                               [RequiresDynamicCode ("Message for --BaseType.VirtualMethodRequires--")]
+                               public virtual void VirtualMethodRequires ()
+                               {
+                               }
                        }
-               }
 
-               class TypeWhichOverridesMethod : BaseType
-               {
-                       [RequiresUnreferencedCode ("Message for --TypeWhichOverridesMethod.VirtualMethodRequires--")]
-                       [RequiresAssemblyFiles ("Message for --TypeWhichOverridesMethod.VirtualMethodRequires--")]
-                       [RequiresDynamicCode ("Message for --TypeWhichOverridesMethod.VirtualMethodRequires--")]
-                       public override void VirtualMethodRequires ()
+                       class TypeWhichOverridesMethod : BaseType
                        {
+                               [RequiresUnreferencedCode ("Message for --TypeWhichOverridesMethod.VirtualMethodRequires--")]
+                               [RequiresAssemblyFiles ("Message for --TypeWhichOverridesMethod.VirtualMethodRequires--")]
+                               [RequiresDynamicCode ("Message for --TypeWhichOverridesMethod.VirtualMethodRequires--")]
+                               public override void VirtualMethodRequires ()
+                               {
+                               }
                        }
-               }
 
-               [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")]
-               [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 ();
-                       tmp.VirtualMethodRequires ();
-               }
+                       [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")]
+                       [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       static void TestCallOnBase ()
+                       {
+                               var tmp = new BaseType ();
+                               tmp.VirtualMethodRequires ();
+                       }
 
-               [LogDoesNotContain ("TypeWhichOverridesMethod.VirtualMethodRequires")]
-               [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")]
-               [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 ();
-                       tmp.VirtualMethodRequires ();
-               }
+                       [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")]
+                       [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       static void TestCallOnOverride ()
+                       {
+                               var tmp = new TypeWhichOverridesMethod ();
+                               tmp.VirtualMethodRequires ();
+                       }
 
-               [LogDoesNotContain ("TypeWhichOverridesMethod.VirtualMethodRequires")]
-               [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")]
-               [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 ();
-                       tmp.VirtualMethodRequires ();
-               }
+                       [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")]
+                       [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       static void TestCallOnOverrideViaBase ()
+                       {
+                               BaseType tmp = new TypeWhichOverridesMethod ();
+                               tmp.VirtualMethodRequires ();
+                       }
 
-               class PropertyBaseType
-               {
-                       public virtual int VirtualPropertyRequires {
-                               [RequiresUnreferencedCode ("Message for --PropertyBaseType.VirtualPropertyRequires--")]
-                               [RequiresAssemblyFiles ("Message for --PropertyBaseType.VirtualPropertyRequires--")]
-                               [RequiresDynamicCode ("Message for --PropertyBaseType.VirtualPropertyRequires--")]
-                               get;
+                       // https://github.com/dotnet/runtime/issues/86008
+                       // This is the "direct reflection" case, which actually behaves differently from indirect (DAM annotation)
+                       // in this case even trimmer will warn on both methods.
+                       [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")]
+                       [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)]
+                       [ExpectedWarning ("IL2026", "--TypeWhichOverridesMethod.VirtualMethodRequires--")]
+                       [ExpectedWarning ("IL3002", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)]
+                       static void TestDirectReflectionAccess ()
+                       {
+                               BaseType tmp = new TypeWhichOverridesMethod ();
+                               typeof (TypeWhichOverridesMethod).GetMethod ("VirtualMethodRequires").Invoke (tmp, Array.Empty<object> ());
                        }
-               }
 
-               class TypeWhichOverridesProperty : PropertyBaseType
-               {
-                       public override int VirtualPropertyRequires {
-                               [RequiresUnreferencedCode ("Message for --TypeWhichOverridesProperty.VirtualPropertyRequires--")]
-                               [RequiresAssemblyFiles ("Message for --TypeWhichOverridesProperty.VirtualPropertyRequires--")]
-                               [RequiresDynamicCode ("Message for --TypeWhichOverridesProperty.VirtualPropertyRequires--")]
-                               get { return 1; }
+                       static void CallMethodWithRequiresOnInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(T instance)
+                       {
+                               typeof(T).GetMethod("VirtualMethodRequires").Invoke(instance, Array.Empty<object> ());
                        }
-               }
 
-               [LogDoesNotContain ("TypeWhichOverridesProperty.VirtualPropertyRequires")]
-               [ExpectedWarning ("IL2026", "--PropertyBaseType.VirtualPropertyRequires--")]
-               [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 ();
-                       _ = tmp.VirtualPropertyRequires;
+                       // https://github.com/dotnet/runtime/issues/86008
+                       [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")]
+                       [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)]
+                       [ExpectedWarning ("IL2026", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.Analyzer)]
+                       //[ExpectedWarning ("IL3002", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)]
+                       //[ExpectedWarning ("IL3050", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)]
+                       static void TestAnnotatedReflectionAccess()
+                       {
+                               CallMethodWithRequiresOnInstance<TypeWhichOverridesMethod>(new TypeWhichOverridesMethod ());
+                       }
+
+                       public static void Test()
+                       {
+                               TestCallOnBase ();
+                               TestCallOnOverride ();
+                               TestCallOnOverrideViaBase ();
+                               TestDirectReflectionAccess ();
+                               TestAnnotatedReflectionAccess ();
+                       }
                }
 
-               [LogDoesNotContain ("ImplementationClass.MethodWithRequires")]
-               [ExpectedWarning ("IL2026", "--IRequires.MethodWithRequires--")]
-               [ExpectedWarning ("IL3002", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
-               [ExpectedWarning ("IL3050", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
-               static void TestInterfaceMethodWithRequires ()
+               class VirtualProperty
                {
-                       IRequires inst = new ImplementationClass ();
-                       inst.MethodWithRequires ();
+                       class PropertyBaseType
+                       {
+                               public virtual int VirtualPropertyRequires {
+                                       [RequiresUnreferencedCode ("Message for --PropertyBaseType.VirtualPropertyRequires--")]
+                                       [RequiresAssemblyFiles ("Message for --PropertyBaseType.VirtualPropertyRequires--")]
+                                       [RequiresDynamicCode ("Message for --PropertyBaseType.VirtualPropertyRequires--")]
+                                       get;
+                               }
+                       }
+
+                       class TypeWhichOverridesProperty : PropertyBaseType
+                       {
+                               public override int VirtualPropertyRequires {
+                                       [RequiresUnreferencedCode ("Message for --TypeWhichOverridesProperty.VirtualPropertyRequires--")]
+                                       [RequiresAssemblyFiles ("Message for --TypeWhichOverridesProperty.VirtualPropertyRequires--")]
+                                       [RequiresDynamicCode ("Message for --TypeWhichOverridesProperty.VirtualPropertyRequires--")]
+                                       get { return 1; }
+                               }
+                       }
+
+                       [ExpectedWarning ("IL2026", "--PropertyBaseType.VirtualPropertyRequires--")]
+                       [ExpectedWarning ("IL3002", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       static void CallOnDerived ()
+                       {
+                               var tmp = new TypeWhichOverridesProperty ();
+                               _ = tmp.VirtualPropertyRequires;
+                       }
+
+                       public static void Test()
+                       {
+                               CallOnDerived ();
+                       }
                }
 
                class BaseReturnType { }
                class DerivedReturnType : BaseReturnType { }
 
-               interface IRequires
+               class InterfaceMethod
                {
-                       [RequiresUnreferencedCode ("Message for --IRequires.MethodWithRequires--")]
-                       [RequiresAssemblyFiles ("Message for --IRequires.MethodWithRequires--")]
-                       [RequiresDynamicCode ("Message for --IRequires.MethodWithRequires--")]
-                       public void MethodWithRequires ();
-               }
+                       interface IRequires
+                       {
+                               [RequiresUnreferencedCode ("Message for --IRequires.MethodWithRequires--")]
+                               [RequiresAssemblyFiles ("Message for --IRequires.MethodWithRequires--")]
+                               [RequiresDynamicCode ("Message for --IRequires.MethodWithRequires--")]
+                               public void MethodWithRequires ();
+                       }
 
-               class ImplementationClass : IRequires
-               {
-                       [RequiresUnreferencedCode ("Message for --ImplementationClass.RequiresMethod--")]
-                       [RequiresAssemblyFiles ("Message for --ImplementationClass.RequiresMethod--")]
-                       [RequiresDynamicCode ("Message for --ImplementationClass.RequiresMethod--")]
-                       public void MethodWithRequires ()
+                       class ImplementationClass : IRequires
                        {
+                               [RequiresUnreferencedCode ("Message for --ImplementationClass.RequiresMethod--")]
+                               [RequiresAssemblyFiles ("Message for --ImplementationClass.RequiresMethod--")]
+                               [RequiresDynamicCode ("Message for --ImplementationClass.RequiresMethod--")]
+                               public void MethodWithRequires ()
+                               {
+                               }
                        }
-               }
 
-               abstract class CovariantReturnBase
-               {
-                       [RequiresUnreferencedCode ("Message for --CovariantReturnBase.GetRequires--")]
-                       [RequiresAssemblyFiles ("Message for --CovariantReturnBase.GetRequires--")]
-                       [RequiresDynamicCode ("Message for --CovariantReturnBase.GetRequires--")]
-                       public abstract BaseReturnType GetRequires ();
-               }
+                       [ExpectedWarning ("IL2026", "--IRequires.MethodWithRequires--")]
+                       [ExpectedWarning ("IL3002", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       static void TestCallViaInterface ()
+                       {
+                               IRequires inst = new ImplementationClass ();
+                               inst.MethodWithRequires ();
+                       }
 
-               class CovariantReturnDerived : CovariantReturnBase
-               {
-                       [RequiresUnreferencedCode ("Message for --CovariantReturnDerived.GetRequires--")]
-                       [RequiresAssemblyFiles ("Message for --CovariantReturnDerived.GetRequires--")]
-                       [RequiresDynamicCode ("Message for --CovariantReturnDerived.GetRequires--")]
-                       public override DerivedReturnType GetRequires ()
+                       [ExpectedWarning ("IL2026", "--ImplementationClass.RequiresMethod--")]
+                       [ExpectedWarning ("IL3002", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       static void TestCallViaImplementationClass ()
+                       {
+                               ImplementationClass inst = new ImplementationClass ();
+                               inst.MethodWithRequires ();
+                       }
+
+                       [ExpectedWarning ("IL2026", "--ImplementationClass.RequiresMethod--")]
+                       [ExpectedWarning ("IL3002", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.NativeAot)]
+                       static void TestDirectReflectionAccess ()
+                       {
+                               typeof (ImplementationClass).GetMethod ("MethodWithRequires").Invoke (new ImplementationClass (), Array.Empty<object> ());
+                       }
+
+                       static void CallMethodWithRequiresOnInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(T instance)
+                       {
+                               typeof (T).GetMethod ("MethodWithRequires").Invoke (new ImplementationClass (), Array.Empty<object> ());
+                       }
+
+                       // https://github.com/dotnet/runtime/issues/86008
+                       // This is a bug in illink, the fact that there's no warning is an analysis hole
+                       [ExpectedWarning ("IL2026", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.NativeAot | Tool.Analyzer)]
+                       [ExpectedWarning ("IL3002", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.NativeAot)]
+                       static void TestAnnotatedReflectionAccess ()
+                       {
+                               CallMethodWithRequiresOnInstance<ImplementationClass> (new ImplementationClass ());
+                       }
+
+                       public static void Test()
                        {
-                               return null;
+                               TestCallViaInterface ();
+                               TestCallViaImplementationClass ();
+                               TestDirectReflectionAccess ();
+                               TestAnnotatedReflectionAccess ();
                        }
                }
 
-               [LogDoesNotContain ("--CovariantReturnBase.GetRequires--")]
-               [ExpectedWarning ("IL2026", "--CovariantReturnDerived.GetRequires--")]
-               [ExpectedWarning ("IL3002", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
-               [ExpectedWarning ("IL3050", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
-               static void TestCovariantReturnCallOnDerived ()
+               class CovariantReturn
                {
-                       var tmp = new CovariantReturnDerived ();
-                       tmp.GetRequires ();
+                       abstract class CovariantReturnBase
+                       {
+                               [RequiresUnreferencedCode ("Message for --CovariantReturnBase.GetRequires--")]
+                               [RequiresAssemblyFiles ("Message for --CovariantReturnBase.GetRequires--")]
+                               [RequiresDynamicCode ("Message for --CovariantReturnBase.GetRequires--")]
+                               public abstract BaseReturnType GetRequires ();
+                       }
+
+                       class CovariantReturnDerived : CovariantReturnBase
+                       {
+                               [RequiresUnreferencedCode ("Message for --CovariantReturnDerived.GetRequires--")]
+                               [RequiresAssemblyFiles ("Message for --CovariantReturnDerived.GetRequires--")]
+                               [RequiresDynamicCode ("Message for --CovariantReturnDerived.GetRequires--")]
+                               public override DerivedReturnType GetRequires ()
+                               {
+                                       return null;
+                               }
+                       }
+
+                       [ExpectedWarning ("IL2026", "--CovariantReturnDerived.GetRequires--")]
+                       [ExpectedWarning ("IL3002", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+                       static void CallOnDerived ()
+                       {
+                               var tmp = new CovariantReturnDerived ();
+                               tmp.GetRequires ();
+                       }
+
+                       public static void Test()
+                       {
+                               CallOnDerived ();
+                       }
                }
 
                class CovariantReturnViaLdftn