Skip to content

Commit e95a658

Browse files
Don't consider ShadowMethods reflectable (#67421)
Fixes #65612. This regression was exposed in #62891 - we had a mismatch between what methods are considered reflectable during scanning vs during optimized compilation due to extra array being injected for reflectable `params` methods on instantiated generic types. There are two potential fixes - either expand the set of methods considered reflectable during scanning, or limit the number of methods considered reflectable in optimized compilation. It doesn't look like we need the expanded set, so going with a restriction instead. The CI may prove me otherwise, so keeping an open mind about this.
1 parent 0c1fbe0 commit e95a658

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -184,16 +184,18 @@ protected virtual void Graph_NewMarkedNode(DependencyNodeCore<NodeFactory> obj)
184184
}
185185

186186
IMethodNode methodNode = methodBodyNode;
187+
if (methodNode != null)
188+
{
189+
if (AllMethodsCanBeReflectable)
190+
_reflectableMethods.Add(methodNode.Method);
191+
}
192+
187193
if (methodNode == null)
188194
methodNode = obj as ShadowConcreteMethodNode;
189195

190196
if (methodNode != null)
191197
{
192198
_methodsGenerated.Add(methodNode.Method);
193-
194-
if (AllMethodsCanBeReflectable)
195-
_reflectableMethods.Add(methodNode.Method);
196-
197199
return;
198200
}
199201

src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs

+23
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ internal static int Run()
4545
TestRecursionInGenericVirtualMethods.Run();
4646
TestRecursionThroughGenericLookups.Run();
4747
TestGvmLookupDependency.Run();
48+
TestInvokeMemberCornerCaseInGenerics.Run();
4849
#if !CODEGEN_CPP
4950
TestNullableCasting.Run();
5051
TestVariantCasting.Run();
@@ -3168,4 +3169,26 @@ public static void Run()
31683169
CatConcepts<Technique, object>();
31693170
}
31703171
}
3172+
3173+
class TestInvokeMemberCornerCaseInGenerics
3174+
{
3175+
class Generic<T>
3176+
{
3177+
public void Method(params T[] ts) { }
3178+
}
3179+
3180+
class Atom { }
3181+
3182+
static Generic<Atom> s_instance = new Generic<Atom>();
3183+
static Type s_atomType = typeof(Atom);
3184+
3185+
public static void Run()
3186+
{
3187+
s_instance.Method(null);
3188+
3189+
// Regression test for https://github.com/dotnet/runtime/issues/65612
3190+
// This requires MethodTable for "Atom[]" - just make sure the compiler didn't crash and we can invoke
3191+
typeof(Generic<>).MakeGenericType(s_atomType).InvokeMember("Method", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, s_instance, new object[] { new Atom() });
3192+
}
3193+
}
31713194
}

0 commit comments

Comments
 (0)