From b6609f25fad5abb834550256eb46f23348d90e29 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Jul 2026 18:53:07 +0000 Subject: [PATCH 1/6] Initial plan From 860048e3fa9c978bfa8662a8b585fb55e378d181 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:44:54 +0000 Subject: [PATCH 2/6] Add ILLink unused annotation regression coverage Co-authored-by: jtschuster <36744439+jtschuster@users.noreply.github.com> --- .../UnusedVirtualMethodAnnotations.cs | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs new file mode 100644 index 00000000000000..9137a74c34d030 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs @@ -0,0 +1,84 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class UnusedVirtualMethodAnnotations + { + [UnconditionalSuppressMessage("Test", "IL2026")] + public static void Main() + { + _ = typeof(TypeOnlyImplementation); + + IUsed used = new UsedImplementation(); + used.Method(typeof(object)); + + IPartiallyUsed partiallyUsed = new PartiallyUsedImplementation(); + partiallyUsed.Method(typeof(object)); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + interface IUnused + { + [RequiresUnreferencedCode(nameof(Method))] + void Method([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type); + } + + class UnusedImplementation : IUnused + { + public void Method(Type type) { } + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + interface ITypeOnly + { + [RequiresUnreferencedCode(nameof(Method))] + void Method([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type); + } + + class TypeOnlyImplementation : ITypeOnly + { + public void Method(Type type) { } + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + interface IUsed + { + [RequiresUnreferencedCode(nameof(Method))] + void Method([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type); + } + + class UsedImplementation : IUsed + { + [ExpectedWarning("IL2046")] + [ExpectedWarning("IL2092")] + public void Method(Type type) { } + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + interface IPartiallyUsed + { + [RequiresUnreferencedCode(nameof(Method))] + void Method([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type); + } + + class PartiallyUsedImplementation : IPartiallyUsed + { + [ExpectedWarning("IL2046")] + [ExpectedWarning("IL2092")] + public void Method(Type type) { } + } + + class UnusedImplementationOfPartiallyUsedInterface : IPartiallyUsed + { + public void Method(Type type) { } + } + } +} From c60ab0a232783a7382b51637b5dcc89ed7bb5690 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 24 Jul 2026 20:25:12 +0000 Subject: [PATCH 3/6] Add UnexpectedWarning annotations for analyzer-only IL2046/IL2092 on unused implementations Co-authored-by: jtschuster <36744439+jtschuster@users.noreply.github.com> --- .../DataFlow/UnusedVirtualMethodAnnotations.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs index 9137a74c34d030..24e4fe1706e5ea 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs @@ -33,6 +33,8 @@ interface IUnused class UnusedImplementation : IUnused { + [UnexpectedWarning("IL2046", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] + [UnexpectedWarning("IL2092", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] public void Method(Type type) { } } @@ -45,6 +47,8 @@ interface ITypeOnly class TypeOnlyImplementation : ITypeOnly { + [UnexpectedWarning("IL2046", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] + [UnexpectedWarning("IL2092", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] public void Method(Type type) { } } @@ -78,6 +82,8 @@ public void Method(Type type) { } class UnusedImplementationOfPartiallyUsedInterface : IPartiallyUsed { + [UnexpectedWarning("IL2046", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] + [UnexpectedWarning("IL2092", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] public void Method(Type type) { } } } From 51884f21d6fac2ae7d9a71bcb3006c2fff049ead Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 24 Jul 2026 20:35:19 +0000 Subject: [PATCH 4/6] Update UnexpectedWarning reason strings to 'Analyzer does not track reachability' Co-authored-by: jtschuster <36744439+jtschuster@users.noreply.github.com> --- .../DataFlow/UnusedVirtualMethodAnnotations.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs index 24e4fe1706e5ea..81095ecfd7cea7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs @@ -33,8 +33,8 @@ interface IUnused class UnusedImplementation : IUnused { - [UnexpectedWarning("IL2046", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] - [UnexpectedWarning("IL2092", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] + [UnexpectedWarning("IL2046", Tool.Analyzer, "Analyzer does not track reachability")] + [UnexpectedWarning("IL2092", Tool.Analyzer, "Analyzer does not track reachability")] public void Method(Type type) { } } @@ -47,8 +47,8 @@ interface ITypeOnly class TypeOnlyImplementation : ITypeOnly { - [UnexpectedWarning("IL2046", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] - [UnexpectedWarning("IL2092", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] + [UnexpectedWarning("IL2046", Tool.Analyzer, "Analyzer does not track reachability")] + [UnexpectedWarning("IL2092", Tool.Analyzer, "Analyzer does not track reachability")] public void Method(Type type) { } } @@ -82,8 +82,8 @@ public void Method(Type type) { } class UnusedImplementationOfPartiallyUsedInterface : IPartiallyUsed { - [UnexpectedWarning("IL2046", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] - [UnexpectedWarning("IL2092", Tool.Analyzer, "https://github.com/dotnet/runtime/pull/130640")] + [UnexpectedWarning("IL2046", Tool.Analyzer, "Analyzer does not track reachability")] + [UnexpectedWarning("IL2092", Tool.Analyzer, "Analyzer does not track reachability")] public void Method(Type type) { } } } From 5bc07dcb888b41c0efe1010a7691628a8faab8b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Jul 2026 15:59:01 +0000 Subject: [PATCH 5/6] Change UnexpectedWarning to ExpectedWarning for analyzer-only IL2046/IL2092 warnings Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com> --- .../DataFlow/UnusedVirtualMethodAnnotations.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs index 81095ecfd7cea7..a0540de6e193ba 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs @@ -33,8 +33,8 @@ interface IUnused class UnusedImplementation : IUnused { - [UnexpectedWarning("IL2046", Tool.Analyzer, "Analyzer does not track reachability")] - [UnexpectedWarning("IL2092", Tool.Analyzer, "Analyzer does not track reachability")] + [ExpectedWarning("IL2046", Tool.Analyzer, "Analyzer does not track reachability")] + [ExpectedWarning("IL2092", Tool.Analyzer, "Analyzer does not track reachability")] public void Method(Type type) { } } @@ -47,8 +47,8 @@ interface ITypeOnly class TypeOnlyImplementation : ITypeOnly { - [UnexpectedWarning("IL2046", Tool.Analyzer, "Analyzer does not track reachability")] - [UnexpectedWarning("IL2092", Tool.Analyzer, "Analyzer does not track reachability")] + [ExpectedWarning("IL2046", Tool.Analyzer, "Analyzer does not track reachability")] + [ExpectedWarning("IL2092", Tool.Analyzer, "Analyzer does not track reachability")] public void Method(Type type) { } } @@ -82,8 +82,8 @@ public void Method(Type type) { } class UnusedImplementationOfPartiallyUsedInterface : IPartiallyUsed { - [UnexpectedWarning("IL2046", Tool.Analyzer, "Analyzer does not track reachability")] - [UnexpectedWarning("IL2092", Tool.Analyzer, "Analyzer does not track reachability")] + [ExpectedWarning("IL2046", Tool.Analyzer, "Analyzer does not track reachability")] + [ExpectedWarning("IL2092", Tool.Analyzer, "Analyzer does not track reachability")] public void Method(Type type) { } } } From ecf57b249b8da8d5be4ac3e7acafdf81298d4043 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Jul 2026 18:59:49 +0000 Subject: [PATCH 6/6] Remove DAM from interface type declarations in UnusedVirtualMethodAnnotations test Co-authored-by: jtschuster <36744439+jtschuster@users.noreply.github.com> --- .../DataFlow/UnusedVirtualMethodAnnotations.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs index a0540de6e193ba..08772a45d4e532 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnusedVirtualMethodAnnotations.cs @@ -24,7 +24,6 @@ public static void Main() partiallyUsed.Method(typeof(object)); } - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] interface IUnused { [RequiresUnreferencedCode(nameof(Method))] @@ -38,7 +37,6 @@ class UnusedImplementation : IUnused public void Method(Type type) { } } - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] interface ITypeOnly { [RequiresUnreferencedCode(nameof(Method))] @@ -52,7 +50,6 @@ class TypeOnlyImplementation : ITypeOnly public void Method(Type type) { } } - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] interface IUsed { [RequiresUnreferencedCode(nameof(Method))] @@ -66,7 +63,6 @@ class UsedImplementation : IUsed public void Method(Type type) { } } - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] interface IPartiallyUsed { [RequiresUnreferencedCode(nameof(Method))]