From 78528e6102e076809a3ae507463c216150272410 Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Tue, 8 Dec 2020 14:40:36 -0800 Subject: [PATCH] Fix pointer type forwarding (dotnet/linker#1679) Sweep step resolves type forwarders and replaces them with direct type refs. There were already special cases for generic instantiations and array, but other type specifications were missing, most notably pointer types. Added handling of all type specifications and added some tests. Commit migrated from https://github.com/dotnet/linker/commit/d0602c4767acf5dcd46700381ce39bd2775de6d7 --- .../src/linker/Linker.Steps/SweepStep.cs | 13 ++++-- .../AttributeArgumentForwarded.cs | 43 +++++++++++++------ .../Dependencies/ForwarderLibrary.cs | 1 + .../Dependencies/ImplementationLibrary.cs | 5 +++ .../ReferenceImplementationLibrary.cs | 5 +++ 5 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/tools/illink/src/linker/Linker.Steps/SweepStep.cs b/src/tools/illink/src/linker/Linker.Steps/SweepStep.cs index bfe7c227cfe41..670242d9ef59e 100644 --- a/src/tools/illink/src/linker/Linker.Steps/SweepStep.cs +++ b/src/tools/illink/src/linker/Linker.Steps/SweepStep.cs @@ -449,16 +449,21 @@ static void UpdateTypeScope (TypeReference type, AssemblyDefinition assembly) if (type.IsWindowsRuntimeProjection) return; - if (type is GenericInstanceType git && git.HasGenericArguments) { + switch (type) { + case GenericInstanceType git: UpdateTypeScope (git.ElementType, assembly); foreach (var ga in git.GenericArguments) UpdateTypeScope (ga, assembly); return; - } - - if (type is ArrayType at) { + case ArrayType at: UpdateTypeScope (at.ElementType, assembly); return; + case PointerType pt: + UpdateTypeScope (pt.ElementType, assembly); + return; + case FunctionPointerType fpt: + // Currently not possible with C#: https://github.com/dotnet/roslyn/issues/48765 + throw new InternalErrorException ($"Function pointer type in custom attribute argument '{fpt}' - currently not supported."); } TypeDefinition td = type.Resolve (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs index 72c26152010c6..171aad0b8b2fc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs @@ -22,50 +22,52 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [RemovedAssembly ("Forwarder.dll")] [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationStruct))] class AttributeArgumentForwarded { static void Main () { - Test_1 (); - Test_1b (); - Test_1c (); - Test_2 (); - Test_3 (); - Test_3a (); + Test_Parameter_TypeRef (); + Test_Parameter_TypeRefMDArray (); + Test_Parameter_PointerTypeRef (); + Test_Property_ArrayOfTypeRefs (); + Test_Field_GenericOfTypeRefArray (); + Test_Field_OpenGeneric (); + Test_Field_ArrayOfPointerTypeRef (); } [Kept] [KeptAttributeAttribute (typeof (TestTypeAttribute))] [TestType (typeof (ImplementationLibrary))] - public static void Test_1 () + public static void Test_Parameter_TypeRef () { } [Kept] [KeptAttributeAttribute (typeof (TestTypeAttribute))] [TestType (typeof (ImplementationLibrary[,][]))] - public static void Test_1b () + public static void Test_Parameter_TypeRefMDArray () { } [Kept] [KeptAttributeAttribute (typeof (TestTypeAttribute))] - [TestType (typeof (ImplementationLibrary[,][]))] - public static void Test_1c () + [TestType (typeof (ImplementationStruct*))] + public static void Test_Parameter_PointerTypeRef () { } [Kept] [KeptAttributeAttribute (typeof (TestTypeAttribute))] [TestType (TestProperty = new object[] { typeof (ImplementationLibrary) })] - public static void Test_2 () + public static void Test_Property_ArrayOfTypeRefs () { } [Kept] [KeptAttributeAttribute (typeof (TestTypeAttribute))] [TestType (TestField = typeof (SomeGenericType))] - public static void Test_3 () + public static void Test_Field_GenericOfTypeRefArray () { } @@ -73,9 +75,24 @@ public static void Test_3 () [Kept] [KeptAttributeAttribute (typeof (TestTypeAttribute))] [TestType (TestField = typeof (SomeGenericType<>))] - public static void Test_3a () + public static void Test_Field_OpenGeneric () { } + + [Kept] + [KeptAttributeAttribute (typeof (TestTypeAttribute))] + [TestType (TestField = new object[] { typeof (ImplementationStruct*) })] + public static void Test_Field_ArrayOfPointerTypeRef () + { + } + + // This hits Roslyn bug https://github.com/dotnet/roslyn/issues/48765 + //[Kept] + //[KeptAttributeAttribute (typeof (TestTypeAttribute))] + //[TestType (TestField = new object[] { typeof (delegate*) })] + //public static void Test_Field_ArrayOfFunctionPointer () + //{ + //} } [KeptBaseType (typeof (Attribute))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary.cs index bb1521525ca01..441a971eb3f85 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary.cs @@ -1,3 +1,4 @@ using System; [assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationStruct))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary.cs index 98fab0dbaa4ad..86a37fdfcff11 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary.cs @@ -13,4 +13,9 @@ public string GetSomeValue () return "Hello"; } } + + public struct ImplementationStruct + { + public int Field; + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationLibrary.cs index ff4def7c9cd35..8796effb1385d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationLibrary.cs @@ -15,5 +15,10 @@ public string GetSomeValue () return null; } } + + public struct ImplementationStruct + { + public int Field; + } #endif }