Skip to content

Commit

Permalink
Fix pointer type forwarding (dotnet/linker#1679)
Browse files Browse the repository at this point in the history
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 dotnet/linker@d0602c4
  • Loading branch information
vitek-karas committed Dec 8, 2020
1 parent e9a278c commit 78528e6
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 17 deletions.
13 changes: 9 additions & 4 deletions src/tools/illink/src/linker/Linker.Steps/SweepStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,60 +22,77 @@ 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<ImplementationLibrary[]>))]
public static void Test_3 ()
public static void Test_Field_GenericOfTypeRefArray ()
{
}


[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*<int, void>) })]
//public static void Test_Field_ArrayOfFunctionPointer ()
//{
//}
}

[KeptBaseType (typeof (Attribute))]
Expand Down
Original file line number Diff line number Diff line change
@@ -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))]
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@ public string GetSomeValue ()
return "Hello";
}
}

public struct ImplementationStruct
{
public int Field;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,10 @@ public string GetSomeValue ()
return null;
}
}

public struct ImplementationStruct
{
public int Field;
}
#endif
}

0 comments on commit 78528e6

Please sign in to comment.