-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[release/5.0] Fix covariant returns with generic return types (#45873)
* Fix covariant returns with generic return types When a covariant return type was an uninstantiated generic type, the ClassLoader::IsCompatibleWith was not working properly. In debug builds, it was asserting because there was no MethodTable for that type and in release builds, it resulted in ExecutionEngineException or an internal CLR error. This change fixes it by using TypeHandle::CanCastTo instead of MethodTable::CanCastTo and adds a regression test for two cases where the problem was observed (Assembly.GetTypes() and creating an instance of a type with a covariant return with a problematic kind of type). * Fix issue 45082 too There were two issues. First, the ClassLoader::ValidateMethodsWithCovariantReturnTypes was called before typeHnd.DoFullyLoad and that resulted in an assert down the call chain of TypeDesc::CanCastTo due to a wrong load level. Second, the SigTypeContext generation for the current MD in the ClassLoader::ValidateMethodsWithCovariantReturnTypes requires the same change for class instantiation as the one that we had for the parent MD. * Fix the issue 45082 in a correct way The call to ClassLoader::ValidateMethodsWithCovariantReturnTypes is now in MethodTable::DoFullyLoad. I have also added a test case that verifies a case that David Wrighton has suggested offline, where there are 3 types... A, B and C. C derives from B which derives from A. B has a bad override which should produce an error. Then, cause C to be fully loaded without otherwise triggering a load of B. Co-authored-by: Jan Vorlicek <janvorli@microsoft.com>
- Loading branch information
1 parent
131a30a
commit fb2e992
Showing
9 changed files
with
167 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Reflection; | ||
|
||
public abstract class Base<T> | ||
{ | ||
public virtual T Get() => throw new NotImplementedException(); | ||
} | ||
|
||
public sealed class CovariantReturn : Base<object> | ||
{ | ||
public override string Get() => throw new NotImplementedException(); | ||
} | ||
|
||
public abstract class ABase | ||
{ | ||
public abstract object this[int index] { get; } | ||
} | ||
|
||
public sealed class Concrete<T> : ABase | ||
where T : class | ||
{ | ||
public override T this[int index] | ||
{ | ||
get | ||
{ | ||
throw null; | ||
} | ||
} | ||
} | ||
|
||
class Parent | ||
{ | ||
public virtual object Value { get; } | ||
} | ||
|
||
class Child<T> : Parent where T : class | ||
{ | ||
public override T Value { get => (T)base.Value; } | ||
} | ||
|
||
class Foo { } | ||
|
||
class Program | ||
{ | ||
static int Main() | ||
{ | ||
Type[] t = Assembly.GetExecutingAssembly().GetTypes(); | ||
new Child<Foo>(); | ||
new CovariantReturn(); | ||
|
||
return 100; | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/tests/Regressions/coreclr/GitHub_45037/test45037.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<CLRTestKind>BuildAndRun</CLRTestKind> | ||
<CLRTestPriority>1</CLRTestPriority> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="test45037.cs" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
public abstract class AComponent { } | ||
public class Component : AComponent { } | ||
|
||
public abstract class Abstract | ||
{ | ||
public abstract IReadOnlyList<AComponent> New { get; } | ||
} | ||
|
||
public sealed class Concrete<T> : Abstract | ||
where T : AComponent | ||
{ | ||
public override IReadOnlyList<T> New => throw null; | ||
} | ||
|
||
class Program | ||
{ | ||
static int Main() | ||
{ | ||
new Concrete<Component>(); | ||
|
||
return 100; | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/tests/Regressions/coreclr/GitHub_45082/test45082.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<CLRTestKind>BuildAndRun</CLRTestKind> | ||
<CLRTestPriority>1</CLRTestPriority> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="test45082.cs" /> | ||
</ItemGroup> | ||
</Project> |