Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>2017-03-09 00:46:28 +0300
committerGitHub <noreply@github.com>2017-03-09 00:46:28 +0300
commit2a2a698372eaa8d1e4259a642b6f0f843994c649 (patch)
treedb3902a4d241fa3640f7903650c610da1edaa98a /tests/src/Simple/Generics/Generics.cs
parent351923c42cf27a953887da33c63cacf2d00ae04e (diff)
Fix vtable stability issue with shared code (#2921)
Pull request #2096 made sure that lazily built vtables of `Foo<X>` and `Foo<Y>` contain the same entries if their canonical forms are the same, but didn't make sure the order of the entries is the same. This can lead to bugs at runtime where the wrong slot is used to dispatch a virtual method call. To make sure the vtables look the same, we need to also sort the vtable.
Diffstat (limited to 'tests/src/Simple/Generics/Generics.cs')
-rw-r--r--tests/src/Simple/Generics/Generics.cs42
1 files changed, 38 insertions, 4 deletions
diff --git a/tests/src/Simple/Generics/Generics.cs b/tests/src/Simple/Generics/Generics.cs
index 918ff7046..3fc509356 100644
--- a/tests/src/Simple/Generics/Generics.cs
+++ b/tests/src/Simple/Generics/Generics.cs
@@ -511,7 +511,7 @@ class Program
class C1 { }
class C2 { }
- class Base<T> where T : class
+ class Base1<T> where T : class
{
public virtual T As(object o)
{
@@ -519,7 +519,7 @@ class Program
}
}
- class Derived<T> : Base<T> where T : class
+ class Derived1<T> : Base1<T> where T : class
{
public T AsToo(object o)
{
@@ -527,14 +527,48 @@ class Program
}
}
+ class Base2<T>
+ {
+ public virtual string Method1() => "Base2.Method1";
+ public virtual string Method2() => "Base2.Method2";
+ }
+
+ class Derived2<T> : Base2<T>
+ {
+ public override string Method1() => "Derived2.Method1";
+ public override string Method2() => "Derived2.Method2";
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static string TestMethod1FromSharedCode<T>(Base2<T> o) => o.Method1();
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static string TestMethod2FromSharedCode<T>(Base2<T> o) => o.Method2();
+
public static void Run()
{
C1 c1 = new C1();
- if (new Derived<C1>().As(c1) != c1)
+ if (new Derived1<C1>().As(c1) != c1)
throw new Exception();
C2 c2 = new C2();
- if (new Derived<C2>().AsToo(c2) != c2)
+ if (new Derived1<C2>().AsToo(c2) != c2)
+ throw new Exception();
+
+ // Also test the stability of the vtables.
+ Base2<string> b1 = new Derived2<string>();
+ if (b1.Method1() != "Derived2.Method1")
+ throw new Exception();
+ Base2<object> b2 = new Derived2<object>();
+ if (b2.Method2() != "Derived2.Method2")
+ throw new Exception();
+ if (TestMethod1FromSharedCode(b2) != "Derived2.Method1")
+ throw new Exception();
+ if (TestMethod1FromSharedCode(b1) != "Derived2.Method1")
+ throw new Exception();
+ if (TestMethod2FromSharedCode(b2) != "Derived2.Method2")
+ throw new Exception();
+ if (TestMethod2FromSharedCode(b1) != "Derived2.Method2")
throw new Exception();
}
}