Skip to content

Commit 7d15ecf

Browse files
authored
Fix covariant return type validation for canon parents (#43843)
The return type validation was rejecting cases when the method being overriden had canon type in its generic arguments. This change fixes the problem by using parent method type instantiation for constructing the SigTypeContext in such case. It also adds a regression test.
1 parent 7b6a578 commit 7d15ecf

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

src/coreclr/src/vm/class.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,9 +1171,12 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT)
11711171
if (!pMD->RequiresCovariantReturnTypeChecking() && !pParentMD->RequiresCovariantReturnTypeChecking())
11721172
continue;
11731173

1174-
// The context used to load the return type of the parent method has to use the generic method arguments
1175-
// of the overriding method, otherwise the type comparison below will not work correctly
1176-
SigTypeContext context1(pParentMD->GetClassInstantiation(), pMD->GetMethodInstantiation());
1174+
Instantiation classInst = pParentMD->GetClassInstantiation();
1175+
if (ClassLoader::IsTypicalSharedInstantiation(classInst))
1176+
{
1177+
classInst = pParentMT->GetInstantiation();
1178+
}
1179+
SigTypeContext context1(classInst, pMD->GetMethodInstantiation());
11771180
MetaSig methodSig1(pParentMD);
11781181
TypeHandle hType1 = methodSig1.GetReturnProps().GetTypeHandleThrowing(pParentMD->GetModule(), &context1, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS);
11791182

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
class Program
2+
{
3+
static int Main(string[] args)
4+
{
5+
System.Console.WriteLine(System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription);
6+
CallC();
7+
CallB();
8+
CallC2();
9+
CallB2();
10+
11+
return 100;
12+
}
13+
14+
static void CallB() => new B();
15+
static void CallC() => new C();
16+
static void CallB2() => new B2();
17+
static void CallC2() => new C2();
18+
}
19+
20+
abstract class A<T>
21+
{
22+
public abstract A<T> M();
23+
}
24+
25+
abstract class A2<T>
26+
{
27+
public abstract A2<T> M<U>();
28+
}
29+
30+
class B : A<string>
31+
{
32+
public override B M() => new B();
33+
}
34+
35+
class B2 : A2<string>
36+
{
37+
public override B2 M<U>() => new B2();
38+
}
39+
40+
class C : A<int>
41+
{
42+
public override C M() => new C();
43+
}
44+
45+
class C2 : A2<int>
46+
{
47+
public override C2 M<U>() => new C2();
48+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<CLRTestKind>BuildAndRun</CLRTestKind>
5+
<CLRTestPriority>1</CLRTestPriority>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<Compile Include="test43763.cs" />
9+
</ItemGroup>
10+
<ItemGroup>
11+
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
12+
</ItemGroup>
13+
</Project>

0 commit comments

Comments
 (0)