More thoroughly check for function pointers (#81344)
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>
Mon, 30 Jan 2023 11:52:26 +0000 (20:52 +0900)
committerGitHub <noreply@github.com>
Mon, 30 Jan 2023 11:52:26 +0000 (20:52 +0900)
Fixes #81117.

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectedFieldNode.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs

index f4cd0c8..2c3378b 100644 (file)
@@ -96,11 +96,17 @@ namespace ILCompiler.DependencyAnalysis
             {
                 // Runtime reflection stack needs to obtain the type handle of the field
                 // (but there's no type handles for function pointers)
-                TypeDesc fieldTypeToCheck = _field.FieldType;
-                while (fieldTypeToCheck.IsParameterizedType)
-                    fieldTypeToCheck = ((ParameterizedType)fieldTypeToCheck).ParameterType;
+                static bool ContainsFunctionPointers(TypeDesc type)
+                {
+                    if (type.IsParameterizedType)
+                        return ContainsFunctionPointers(((ParameterizedType)type).ParameterType);
+                    foreach (TypeDesc instArg in type.Instantiation)
+                        if (ContainsFunctionPointers(instArg))
+                            return true;
+                    return type.IsFunctionPointer;
+                }
 
-                if (!fieldTypeToCheck.IsFunctionPointer)
+                if (!ContainsFunctionPointers(_field.FieldType))
                     dependencies.Add(factory.MaximallyConstructableType(_field.FieldType.NormalizeInstantiation()), "Type of the field");
             }
 
index d0c340a..b541f52 100644 (file)
@@ -80,7 +80,16 @@ namespace ILCompiler.DependencyAnalysis
 
                     // Function pointers are not supported yet.
                     // https://github.com/dotnet/runtime/issues/71883
-                    if (type.IsFunctionPointer)
+                    static bool ContainsFunctionPointers(TypeDesc type)
+                    {
+                        if (type.IsParameterizedType)
+                            return ContainsFunctionPointers(((ParameterizedType)type).ParameterType);
+                        foreach (TypeDesc instArg in type.Instantiation)
+                            if (ContainsFunctionPointers(instArg))
+                                return true;
+                        return type.IsFunctionPointer;
+                    }
+                    if (ContainsFunctionPointers(type))
                         return;
 
                     TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific);