diff --git a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases.Expectations/ILTrim.Tests.Cases.Expectations.csproj b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases.Expectations/ILTrim.Tests.Cases.Expectations.csproj
index 8b526db9b74..72f2e53fa75 100644
--- a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases.Expectations/ILTrim.Tests.Cases.Expectations.csproj
+++ b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases.Expectations/ILTrim.Tests.Cases.Expectations.csproj
@@ -2,7 +2,6 @@
net6.0
- enable
enable
x64;x86
diff --git a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/Basic/FunctionPointer.cs b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/Basic/FunctionPointer.cs
new file mode 100644
index 00000000000..608e0ab8110
--- /dev/null
+++ b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/Basic/FunctionPointer.cs
@@ -0,0 +1,27 @@
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+[module:KeptAttributeAttribute(typeof(System.Security.UnverifiableCodeAttribute))]
+
+namespace Mono.Linker.Tests.Cases.Basic
+{
+ [Kept]
+ [SetupCompileArgument("/unsafe")]
+ unsafe class FunctionPointer
+ {
+ [Kept]
+ static void Main()
+ {
+ MethodTakingFunctionPointer(null);
+ }
+
+ [Kept]
+ static void MethodTakingFunctionPointer(delegate* del) { }
+
+ [Kept]
+ class OneType { }
+
+ [Kept]
+ class OtherType { }
+ }
+}
diff --git a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/ILTrim.Tests.Cases.csproj b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/ILTrim.Tests.Cases.csproj
index 1f0a194fe4b..da3847d6585 100644
--- a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/ILTrim.Tests.Cases.csproj
+++ b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/ILTrim.Tests.Cases.csproj
@@ -3,6 +3,7 @@
net6.0
x64;x86
+ true
$(DefineConstants);INCLUDE_EXPECTATIONS
diff --git a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureAnalyzer.cs b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureAnalyzer.cs
index f9cbaa76010..75f9a67cbef 100644
--- a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureAnalyzer.cs
+++ b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureAnalyzer.cs
@@ -46,6 +46,7 @@ private void AnalyzeType()
private void AnalyzeType(SignatureTypeCode typeCode)
{
+ again:
switch (typeCode)
{
case SignatureTypeCode.Void:
@@ -85,7 +86,8 @@ private void AnalyzeType(SignatureTypeCode typeCode)
case SignatureTypeCode.RequiredModifier:
case SignatureTypeCode.OptionalModifier:
AnalyzeCustomModifier(typeCode);
- break;
+ typeCode = _blobReader.ReadSignatureTypeCode();
+ goto again;
case SignatureTypeCode.GenericTypeInstance:
_blobReader.ReadCompressedInteger();
Dependencies.Add(_factory.GetNodeForToken(_module, _blobReader.ReadTypeHandle()), "Signature reference");
@@ -96,7 +98,8 @@ private void AnalyzeType(SignatureTypeCode typeCode)
}
break;
case SignatureTypeCode.FunctionPointer:
- throw new NotImplementedException();
+ AnalyzeMethodSignature();
+ break;
default:
throw new BadImageFormatException();
}
diff --git a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureRewriter.cs b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureRewriter.cs
index 28b158c5372..d952e04f248 100644
--- a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureRewriter.cs
+++ b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/EcmaSignatureRewriter.cs
@@ -32,6 +32,7 @@ private void RewriteType(SignatureTypeEncoder encoder)
private void RewriteType(SignatureTypeCode typeCode, SignatureTypeEncoder encoder)
{
+ again:
switch (typeCode)
{
case SignatureTypeCode.Boolean:
@@ -96,7 +97,8 @@ private void RewriteType(SignatureTypeCode typeCode, SignatureTypeEncoder encode
case SignatureTypeCode.RequiredModifier:
case SignatureTypeCode.OptionalModifier:
RewriteCustomModifier(typeCode, encoder.CustomModifiers());
- break;
+ typeCode = _blobReader.ReadSignatureTypeCode();
+ goto again;
case SignatureTypeCode.GenericTypeInstance:
{
int classOrValueType = _blobReader.ReadCompressedInteger();
@@ -119,7 +121,15 @@ private void RewriteType(SignatureTypeCode typeCode, SignatureTypeEncoder encode
case SignatureTypeCode.TypedReference:
encoder.PrimitiveType(PrimitiveTypeCode.TypedReference); break;
case SignatureTypeCode.FunctionPointer:
- throw new NotImplementedException();
+ {
+ SignatureHeader header = _blobReader.ReadSignatureHeader();
+ int arity = header.IsGeneric ? _blobReader.ReadCompressedInteger() : 0;
+ MethodSignatureEncoder sigEncoder = encoder.FunctionPointer(header.CallingConvention, 0, arity);
+ int count = _blobReader.ReadCompressedInteger();
+ sigEncoder.Parameters(count, out ReturnTypeEncoder retTypeEncoder, out ParametersEncoder paramEncoder);
+ RewriteMethodSignature(count, retTypeEncoder, paramEncoder);
+ }
+ break;
default:
throw new BadImageFormatException();
}
@@ -185,6 +195,11 @@ private void RewriteMethodSignature(BlobBuilder blobBuilder, SignatureHeader hea
sigEncoder.Parameters(count, out ReturnTypeEncoder returnTypeEncoder, out ParametersEncoder paramsEncoder);
+ RewriteMethodSignature(count, returnTypeEncoder, paramsEncoder);
+ }
+
+ private void RewriteMethodSignature(int count, ReturnTypeEncoder returnTypeEncoder, ParametersEncoder paramsEncoder)
+ {
bool isByRef = false;
againReturnType:
SignatureTypeCode typeCode = _blobReader.ReadSignatureTypeCode();