diff --git a/src/mono/mono/metadata/class-setup-vtable.c b/src/mono/mono/metadata/class-setup-vtable.c index bc949189a3c125..e9dc6997d89e7b 100644 --- a/src/mono/mono/metadata/class-setup-vtable.c +++ b/src/mono/mono/metadata/class-setup-vtable.c @@ -1656,6 +1656,10 @@ check_vtable_covariant_override_impls (MonoClass *klass, MonoMethod **vtable, in break; MonoMethod *prev_impl = cur_class->vtable[slot]; + // if the current class re-abstracted the method, it may not be there. + if (!prev_impl) + continue; + if (prev_impl != last_checked_prev_override) { /* * the new impl should be subsumed by the prior one, ie this diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideReabstracted.cs b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideReabstracted.cs new file mode 100644 index 00000000000000..f0f461777e7002 --- /dev/null +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideReabstracted.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + + +namespace ReproMAUI6811; + +public static class Program +{ + public static int Main() + { + Leaf l = new Leaf(); + + if (l.getI().ToString() != "Leaf") + return 1; + if (((Intermediate)l).getI().ToString() != "Leaf") + return 2; + if (((PseudoBase)l).getI().ToString() != "Leaf") + return 3; + if (((Base)l).getI().ToString() != "Leaf") + return 4; + return 100; + } +} + +public abstract class Base { + public abstract I getI(); +} + +public class PseudoBase : Base { + public override I getI() => new C ("PseudoBase"); +} + +public abstract class Intermediate : PseudoBase { + public override abstract I getI(); +} + +public class Leaf : Intermediate { + public Leaf() {} + public override C getI() { return new C ("Leaf"); } +} + +public interface I {} + +public class C : I { + private readonly string _repr; + public C(string s) { _repr = s; } + public override string ToString() => _repr; +} + + diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideReabstracted.csproj b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideReabstracted.csproj new file mode 100644 index 00000000000000..570644f1dbcb7e --- /dev/null +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideReabstracted.csproj @@ -0,0 +1,8 @@ + + + Exe + + + + +