From bfddbfc92e88343baff004daecead07a1415a2f1 Mon Sep 17 00:00:00 2001 From: Jackson Schuster Date: Tue, 1 Nov 2022 14:34:49 -0700 Subject: [PATCH 1/4] Don't mark an override if the declaring type isn't marked --- src/linker/Linker.Steps/MarkStep.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs index e8c29e29e075..7f26bea95161 100644 --- a/src/linker/Linker.Steps/MarkStep.cs +++ b/src/linker/Linker.Steps/MarkStep.cs @@ -723,6 +723,8 @@ void ProcessVirtualMethod (MethodDefinition method) // TODO: Move interface method marking logic here https://github.com/dotnet/linker/issues/3090 bool ShouldMarkOverrideForBase (OverrideInformation overrideInformation) { + if (!Annotations.IsMarked (overrideInformation.Override.DeclaringType)) + return false; if (overrideInformation.IsOverrideOfInterfaceMember) { _interfaceOverrides.Add ((overrideInformation, ScopeStack.CurrentScope)); return false; From 33aa25a735db7a31dda1376fda5a3300ca10f941 Mon Sep 17 00:00:00 2001 From: Jackson Schuster Date: Tue, 1 Nov 2022 15:01:03 -0700 Subject: [PATCH 2/4] Test for base is abstract is derived is not marked --- .../Inheritance.VirtualMethodsTests.g.cs | 6 +++ ...rrideOfAbstractInUnmarkedClassIsRemoved.cs | 45 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs index a7cadcdb33e0..5ddfcf4f3b67 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs @@ -27,6 +27,12 @@ public Task NeverInstantiatedTypeWithBaseInCopiedAssembly () return RunTest (allowMissingWarnings: true); } + [Fact] + public Task OverrideInUnmarkedClassIsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + [Fact] public Task UnusedTypeWithOverrideOfVirtualMethodIsRemoved () { diff --git a/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs b/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs new file mode 100644 index 000000000000..2e4184268502 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs @@ -0,0 +1,45 @@ +// 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.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.Inheritance.VirtualMethods +{ + public class OverrideInUnmarkedClassIsRemoved + { + [Kept] + public static void Main () + { + MarkedBase x = new MarkedDerived (); + x.Method (); + } + + [Kept] + [KeptMember (".ctor()")] + abstract class MarkedBase + { + [Kept] + public abstract int Method (); + } + + [Kept] + [KeptMember (".ctor()")] + [KeptBaseType (typeof (MarkedBase))] + class MarkedDerived : MarkedBase + { + [Kept] + public override int Method () => 1; + } + + class UnmarkedDerived : MarkedBase + { + public override int Method () => 1; + } + } +} From d797be196434b61a0eafd139269f4872386211a7 Mon Sep 17 00:00:00 2001 From: Jackson Schuster Date: Tue, 1 Nov 2022 15:25:22 -0700 Subject: [PATCH 3/4] Rename test class to match file --- .../OverrideOfAbstractInUnmarkedClassIsRemoved.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs b/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs index 2e4184268502..a373c28e2266 100644 --- a/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs +++ b/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs @@ -11,7 +11,7 @@ namespace Mono.Linker.Tests.Cases.Inheritance.VirtualMethods { - public class OverrideInUnmarkedClassIsRemoved + public class OverrideOfAbstractInUnmarkedClassIsRemoved { [Kept] public static void Main () From 53a696b219f94bd408840d28b9daa76981ebd4c5 Mon Sep 17 00:00:00 2001 From: Jackson Schuster Date: Wed, 2 Nov 2022 10:21:40 -0500 Subject: [PATCH 4/4] Add more variations to the test --- ...rrideOfAbstractInUnmarkedClassIsRemoved.cs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs b/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs index a373c28e2266..366fd6a3f34f 100644 --- a/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs +++ b/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/OverrideOfAbstractInUnmarkedClassIsRemoved.cs @@ -18,6 +18,12 @@ public static void Main () { MarkedBase x = new MarkedDerived (); x.Method (); + + UsedSecondLevelTypeWithAbstractBase y = new (); + y.Method (); + + UsedSecondLevelType z = new (); + z.Method (); } [Kept] @@ -41,5 +47,51 @@ class UnmarkedDerived : MarkedBase { public override int Method () => 1; } + + [Kept] + [KeptMember (".ctor()")] + [KeptBaseType (typeof (MarkedBase))] + class UnusedIntermediateType : MarkedBase + { + [Kept] + public override int Method () => 1; + } + + [Kept] + [KeptMember (".ctor()")] + [KeptBaseType (typeof (UnusedIntermediateType))] + class UsedSecondLevelType : UnusedIntermediateType + { + [Kept] + public override int Method () => 1; + } + + [Kept] + [KeptMember (".ctor()")] + [KeptBaseType (typeof (MarkedBase))] + abstract class UnusedIntermediateTypeWithAbstractOverride : MarkedBase + { + [Kept] + public abstract override int Method (); + } + + [Kept] + [KeptMember (".ctor()")] + [KeptBaseType (typeof (UnusedIntermediateTypeWithAbstractOverride))] + class UsedSecondLevelTypeWithAbstractBase : UnusedIntermediateTypeWithAbstractOverride + { + [Kept] + public override int Method () => 1; + } + + class UnusedSecondLevelTypeWithAbstractBase : UnusedIntermediateTypeWithAbstractOverride + { + public override int Method () => 1; + } + + class UnusedSecondLevelType : UnusedIntermediateType + { + public override int Method () => 1; + } } }