From dd761f75c38eca0bae79597436320510ffc80702 Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Fri, 28 May 2021 20:35:54 +0200 Subject: Fix applying All annotation on a type from "copy" assembly (#2060) (#2064) "Copy" assembly calls `MarkEntireType` on all types in the assembly, but it specified to not include base and interface types. We cache if a type was marked as a whole, so to not repeat the process (and also to avoid potential recursion). But the cache doesn't differentiate if the type was mark with its base/interface types or not. So in the "copy" assembly case, the type is first marked without base/interface marking, and that is cached. Later on we apply the All annotation to the type, which calls `MarkEntireType` again, but since it's already cached it doesn't do anything. But All annotation should preserve base/interface types as well, which will not happen in this case. Fixed this by making the cache aware of the base/interface flag and repeat the marking if base/interface is requested even if the type has already been marked as a whole but without base/interface marking. Added a test case. --- .../Dependencies/MemberTypesAllBaseTypeAssembly.cs | 50 +++++++++++++ .../DataFlow/MemberTypesAllOnCopyAssembly.cs | 82 ++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 test/Mono.Linker.Tests.Cases/DataFlow/Dependencies/MemberTypesAllBaseTypeAssembly.cs create mode 100644 test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs (limited to 'test/Mono.Linker.Tests.Cases/DataFlow') diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/Dependencies/MemberTypesAllBaseTypeAssembly.cs b/test/Mono.Linker.Tests.Cases/DataFlow/Dependencies/MemberTypesAllBaseTypeAssembly.cs new file mode 100644 index 000000000..63d3fa11e --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/Dependencies/MemberTypesAllBaseTypeAssembly.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Mono.Linker.Tests.Cases.DataFlow.Dependencies +{ + public class MemberTypesAllBaseType + { + static MemberTypesAllBaseType () { } + public MemberTypesAllBaseType () { } + private MemberTypesAllBaseType (bool _) { } + + public void PublicMethod () { } + private void PrivateMethod () { } + + public static void PublicStaticMethod () { } + private static void PrivateStaticMethod () { } + + public int PublicField; + private int PrivateField; + public static int PublicStaticField; + private static int PrivateStaticField; + + public bool PublicProperty { get; set; } + private bool PrivateProperty { get; set; } + public static bool PublicStaticProperty { get; set; } + private static bool PrivateStaticProperty { get; set; } + + public event EventHandler PublicEvent; + private event EventHandler PrivateEvent; + public static event EventHandler PublicStaticEvent; + private static event EventHandler PrivateStaticEvent; + + public class PublicNestedType + { + private void PrivateMethod () { } + } + + private class PrivateNestedType + { + private void PrivateMethod () { } + } + } +} diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs new file mode 100644 index 000000000..152a935b9 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.DataFlow.Dependencies; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SetupCompileBefore ("base.dll", new[] { "Dependencies/MemberTypesAllBaseTypeAssembly.cs" })] + [KeptAssembly ("base.dll")] + [SetupLinkerAction ("link", "base")] + [SetupLinkerAction ("copy", "test")] + + [KeptTypeInAssembly ("base.dll", "Mono.Linker.Tests.Cases.DataFlow.Dependencies.MemberTypesAllBaseType")] + [KeptMemberInAssembly ("base.dll", "Mono.Linker.Tests.Cases.DataFlow.Dependencies.MemberTypesAllBaseType", new string[] { + ".cctor()", + ".ctor()", + ".ctor(System.Boolean)", + "PublicMethod()", + "PrivateMethod()", + "PublicStaticMethod()", + "PrivateStaticMethod()", + "PublicField", + "PrivateField", + "PublicStaticField", + "PrivateStaticField", + "PublicProperty", + "get_PublicProperty()", + "set_PublicProperty(System.Boolean)", + "PrivateProperty", + "get_PrivateProperty()", + "set_PrivateProperty(System.Boolean)", + "PublicStaticProperty", + "get_PublicStaticProperty()", + "set_PublicStaticProperty(System.Boolean)", + "PrivateStaticProperty", + "get_PrivateStaticProperty()", + "set_PrivateStaticProperty(System.Boolean)", + "PublicEvent", + "add_PublicEvent(System.EventHandler`1)", + "remove_PublicEvent(System.EventHandler`1)", + "PrivateEvent", + "add_PrivateEvent(System.EventHandler`1)", + "remove_PrivateEvent(System.EventHandler`1)", + "PublicStaticEvent", + "add_PublicStaticEvent(System.EventHandler`1)", + "remove_PublicStaticEvent(System.EventHandler`1)", + "PrivateStaticEvent", + "add_PrivateStaticEvent(System.EventHandler`1)", + "remove_PrivateStaticEvent(System.EventHandler`1)", + })] + + [KeptTypeInAssembly ("base.dll", "Mono.Linker.Tests.Cases.DataFlow.Dependencies.MemberTypesAllBaseType/PublicNestedType")] + [KeptMemberInAssembly ("base.dll", "Mono.Linker.Tests.Cases.DataFlow.Dependencies.MemberTypesAllBaseType/PublicNestedType", new string[] { "PrivateMethod()" })] + + [KeptTypeInAssembly ("base.dll", "Mono.Linker.Tests.Cases.DataFlow.Dependencies.MemberTypesAllBaseType/PrivateNestedType")] + [KeptMemberInAssembly ("base.dll", "Mono.Linker.Tests.Cases.DataFlow.Dependencies.MemberTypesAllBaseType/PrivateNestedType", new string[] { "PrivateMethod()" })] + + [KeptMember (".ctor()")] + public class MemberTypesAllOnCopyAssembly + { + public static void Main () + { + typeof (TestType).RequiresAll (); + } + + [Kept] + [KeptBaseType (typeof (MemberTypesAllBaseType))] + [KeptMember (".ctor()")] + class TestType : MemberTypesAllBaseType + { + } + } +} -- cgit v1.2.3