Skip to content

Commit ce10f6f

Browse files
Ensure we track MakeGenericType (#118479)
...even if there's no member access following the call. This was found in https://github.com/dotnet/runtime/pull/118060/files#r2247963234 but the test case I'm adding is also failing in .NET 9 and doesn't require an IL-only repro to hit because all we need is a struct.
1 parent f187449 commit ce10f6f

File tree

2 files changed

+71
-6
lines changed

2 files changed

+71
-6
lines changed

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,24 @@ private partial bool TryHandleIntrinsic(
9090
}
9191
}
9292
}
93-
else if (typeInstantiated.Instantiation.IsConstrainedToBeReferenceTypes())
94-
{
95-
// This will always succeed thanks to the runtime type loader
96-
}
9793
else
9894
{
99-
triggersWarning = true;
100-
}
95+
if (typeInstantiated.Instantiation.IsConstrainedToBeReferenceTypes())
96+
{
97+
// This will always succeed thanks to the runtime type loader
98+
}
99+
else
100+
{
101+
triggersWarning = true;
102+
}
101103

104+
// This should technically be in the IsConstrainedToBeReferenceTypes branch above
105+
// but we have trim warning suppressions in dotnet/runtime and elsewhere that rely on the implementation
106+
// detail that reference type instantiations will work, even if the generic is not
107+
// constrained to be a reference type.
108+
// MarkType will try to come up with a reference type type loader template.
109+
_reflectionMarker.MarkType(_diagnosticContext.Origin, typeInstantiated, "MakeGenericType");
110+
}
102111
}
103112
else if (value == NullValue.Instance)
104113
{

src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ private static int Main()
7676
Test105034Regression.Run();
7777
TestMethodsNeededFromNativeLayout.Run();
7878
TestFieldAndParamMetadata.Run();
79+
TestActivationWithoutConstructor.Run();
80+
TestNestedMakeGeneric.Run();
7981

8082
//
8183
// Mostly functionality tests
@@ -859,6 +861,60 @@ public static void Run()
859861
}
860862
}
861863

864+
class TestActivationWithoutConstructor
865+
{
866+
public static void Run()
867+
{
868+
{
869+
object o = Activator.CreateInstance(typeof(StructForCreateInstanceDirect<>).MakeGenericType(GetTheType()));
870+
if (!o.ToString().Contains(nameof(StructForCreateInstanceDirect<>)))
871+
throw new Exception();
872+
}
873+
874+
{
875+
object o = CreateInstance(typeof(StructForCreateInstanceIndirect<>).MakeGenericType(GetTheType()));
876+
if (!o.ToString().Contains(nameof(StructForCreateInstanceIndirect<>)))
877+
throw new Exception();
878+
879+
static object CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type t)
880+
=> Activator.CreateInstance(t);
881+
}
882+
883+
{
884+
object o = RuntimeHelpers.GetUninitializedObject(typeof(StructForGetUninitializedObject<>).MakeGenericType(GetTheType()));
885+
if (!o.ToString().Contains(nameof(StructForGetUninitializedObject<>)))
886+
throw new Exception();
887+
}
888+
889+
[MethodImpl(MethodImplOptions.NoInlining)]
890+
static Type GetTheType() => typeof(Atom);
891+
}
892+
893+
class Atom;
894+
895+
struct StructForCreateInstanceDirect<T> where T : class;
896+
struct StructForCreateInstanceIndirect<T> where T : class;
897+
struct StructForGetUninitializedObject<T> where T : class;
898+
}
899+
900+
class TestNestedMakeGeneric
901+
{
902+
class Outie<T> where T : class;
903+
class Innie<T> where T : class;
904+
class Atom;
905+
906+
public static void Run()
907+
{
908+
Type inner = typeof(Innie<>).MakeGenericType(GetAtom());
909+
Type outer = typeof(Outie<>).MakeGenericType(inner);
910+
911+
Console.WriteLine(Activator.CreateInstance(outer));
912+
913+
[MethodImpl(MethodImplOptions.NoInlining)]
914+
static Type GetAtom() => typeof(Atom);
915+
}
916+
}
917+
862918
class TestCreateDelegate
863919
{
864920
internal class Greeter

0 commit comments

Comments
 (0)