diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs index c2caeb24b3341f..da72ea35cb05b0 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs @@ -365,8 +365,8 @@ public override DictionaryLayoutNode GetLayout(TypeSystemEntity methodOrType) private class ScannedDevirtualizationManager : DevirtualizationManager { private HashSet _constructedTypes = new HashSet(); + private HashSet _canonConstructedTypes = new HashSet(); private HashSet _unsealedTypes = new HashSet(); - private HashSet _abstractButNonabstractlyOverriddenTypes = new HashSet(); public ScannedDevirtualizationManager(ImmutableArray> markedNodes) { @@ -390,16 +390,13 @@ public ScannedDevirtualizationManager(ImmutableArray + diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/Devirtualization.cs b/src/tests/nativeaot/SmokeTests/UnitTests/Devirtualization.cs index 73e3ab4d3064fb..5954c6118e6696 100644 --- a/src/tests/nativeaot/SmokeTests/UnitTests/Devirtualization.cs +++ b/src/tests/nativeaot/SmokeTests/UnitTests/Devirtualization.cs @@ -12,6 +12,7 @@ internal static int Run() { RegressionBug73076.Run(); DevirtualizationCornerCaseTests.Run(); + DevirtualizeIntoUnallocatedGenericType.Run(); return 100; } @@ -111,4 +112,28 @@ public static void Run() TestIntf2((IIntf2)Activator.CreateInstance(typeof(Intf2Impl2<>).MakeGenericType(typeof(object))), 456); } } + + class DevirtualizeIntoUnallocatedGenericType + { + class Never { } + + class SomeGeneric + { + public virtual object GrabObject() => null; + } + + sealed class SomeUnallocatedClass : SomeGeneric + { + public override object GrabObject() => new Never(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static SomeUnallocatedClass GrabInst() => null; + + public static void Run() + { + if (GrabInst() != null) + GrabInst().GrabObject(); + } + } }