diff --git a/docs/workflow/README.md b/docs/workflow/README.md index 74bbc892f3efa..332b5a6298122 100644 --- a/docs/workflow/README.md +++ b/docs/workflow/README.md @@ -78,12 +78,14 @@ Now you know about configurations and how we use them, so now you will want to r * [Building CoreCLR runtime](/docs/workflow/building/coreclr/README.md) * [Building Mono runtime](/docs/workflow/building/mono/README.md) +* [Building NativeAOT runtime](/docs/workflow/building/coreclr/nativeaot.md) * [Building Libraries](/docs/workflow/building/libraries/README.md) After that, here's information about how to run tests: * [Testing CoreCLR runtime](/docs/workflow/testing/coreclr/testing.md) * [Testing Mono runtime](/docs/workflow/testing/mono/testing.md) +* [Testing NativeAOT runtime](/docs/workflow/building/coreclr/nativeaot.md#running-tests) * [Testing Libraries](/docs/workflow/testing/libraries/testing.md) And how to measure performance: diff --git a/docs/workflow/building/coreclr/nativeaot.md b/docs/workflow/building/coreclr/nativeaot.md index b9b137464e8e3..0ab5dc1d25887 100644 --- a/docs/workflow/building/coreclr/nativeaot.md +++ b/docs/workflow/building/coreclr/nativeaot.md @@ -87,6 +87,8 @@ If you haven't built the tests yet, run `src\tests\build.cmd nativeaot [Debug|Re To run all the tests that got built, run `src\tests\run.cmd runnativeaottests [Debug|Release]` on Windows, or `src/tests/run.sh --runnativeaottests [Debug|Release]` on Linux. The `Debug`/`Release` flag should match the flag that was passed to `build.cmd` in the previous step. +To build an individual test, follow the instructions for compiling a individual test project located in [Building an Individual Test](/docs/workflow/testing/coreclr/testing.md#building-an-individual-test), but add `/t:BuildNativeAot /p:TestBuildMode=nativeaot` to the build command. + To run an individual test (after it was built), navigate to the `artifacts\tests\coreclr\[windows|linux|osx[.x64.[Debug|Release]\$path_to_test` directory. `$path_to_test` matches the subtree of `src\tests`. You should see a `[.cmd|.sh]` file there. This file is a script that will compile and launch the individual test for you. Before invoking the script, set the following environment variables: * CORE_ROOT=$repo_root\artifacts\tests\coreclr\[windows|linux|osx].x64.[Debug|Release]\Tests\Core_Root diff --git a/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs b/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs index 330296b18dbfa..d87331f3926b3 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs @@ -461,7 +461,26 @@ private static void FindBaseUnificationGroup(MetadataType currentType, Unificati // Unless the current type has a name/sig match for the group, look to the base type to define the unification group further if ((nameSigMatchMethod == null) && (baseType != null)) { + // TODO! Consider if we should do this check even if the virtual name/sig match finds something. + // We may want to build up a unification group for the base just to check the further MethodImpl case here. FindBaseUnificationGroup(baseType, unificationGroup); + + // We should check to see if a the DefiningMethod on the base unification group is overriden via MethodImpl + // TODO! check to see if we need to check for MethodImpls affecting other members of the unification group + // other than the defining method + if (unificationGroup.DefiningMethod != null) + { + methodImpl = FindImplFromDeclFromMethodImpls(currentType, unificationGroup.DefiningMethod); + if (methodImpl != null) + { + if (methodImpl.RequiresSlotUnification()) + { + unificationGroup.AddMethodRequiringSlotUnification(unificationGroup.DefiningMethod); + unificationGroup.AddMethodRequiringSlotUnification(methodImpl); + } + unificationGroup.SetDefiningMethod(methodImpl); + } + } } Debug.Assert(unificationGroup.IsInGroupOrIsDefiningSlot(originalDefiningMethod)); diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/Platform.cs b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/Platform.cs index a2c1a1e06ad60..f398474bb45ac 100644 --- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/Platform.cs +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/Platform.cs @@ -247,11 +247,17 @@ public static class RuntimeFeature public const string ByRefLikeGenerics = nameof(ByRefLikeGenerics); public const string UnmanagedSignatureCallingConvention = nameof(UnmanagedSignatureCallingConvention); public const string VirtualStaticsInInterfaces = nameof(VirtualStaticsInInterfaces); + public const string CovariantReturnsOfClasses = "CovariantReturnsOfClasses"; } internal sealed class IntrinsicAttribute : Attribute { } + + public sealed partial class PreserveBaseOverridesAttribute : System.Attribute + { + public PreserveBaseOverridesAttribute() { } + } } namespace System.Runtime.Intrinsics diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/VirtualFunctionOverride.cs b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/VirtualFunctionOverride.cs index 8440dfc3cd00e..76b16f3ca46c9 100644 --- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/VirtualFunctionOverride.cs +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/VirtualFunctionOverride.cs @@ -60,4 +60,44 @@ unsafe class FunctionPointerOverloadDerived : FunctionPointerOverloadBase public override Type Method(delegate* unmanaged[Stdcall, SuppressGCTransition] p) => null; public override Type Method(delegate* p) => null; } + + class BaseCovariant + { + public virtual BaseCovariant FromType() + { + return new BaseCovariant(); + } + } + + class ImplCovariant : BaseCovariant + { + public override ImplCovariant FromType() + { + return new ImplCovariant(); + } + } + + class SubImplCovariant : ImplCovariant + { + public override SubImplCovariant FromType() + { + return new SubImplCovariant(); + } + } + + class SubImplCovariant2 : ImplCovariant + { + public override ImplCovariant FromType() + { + return new ImplCovariant(); + } + } + + class SubSubImplCovariant : SubImplCovariant2 + { + public override SubSubImplCovariant FromType() + { + return new SubSubImplCovariant(); + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/ILTestAssembly.ilproj b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/ILTestAssembly.ilproj index 22c49cc067658..9cf5774a8a5bb 100644 --- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/ILTestAssembly.ilproj +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/ILTestAssembly.ilproj @@ -19,6 +19,7 @@ + diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/PreserveBaseOverridesAttibuteTesting.il b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/PreserveBaseOverridesAttibuteTesting.il new file mode 100644 index 0000000000000..54bc08c49083b --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/PreserveBaseOverridesAttibuteTesting.il @@ -0,0 +1,1275 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// This test validates the behavior in the presence/absence of the PreserveBaseOverridesAttribute. +// Each test scenario will have 3 layers of type inheritance (T1,T2,T3), and we test the following scenarios: +// +// Scenario A: Attribute placed T1's MethodDecl (attribute treated as NOP - only applicable to MethodImpls) +// ============================================================================== +// Scenario A.1: T2 explicitly overrides T1's, T3 explicitly overrides T1's MethodDecl +// Scenario A.2: T2 explicitly overrides T1's, T3 explicitly overrides T2's MethodImpl +// Scenario A.3: T2 explicitly overrides T1's, T3 implicitly overrides T1's MethodDecl +// Scenario A.4: T2 explicitly overrides T1's, T3 implicitly overrides T2's MethodImpl +// Scenario A.5: T2 implicitly overrides T1's, T3 explicitly overrides T1's method +// Scenario A.6: T2 implicitly overrides T1's, T3 explicitly overrides T2's method +// Scenario A.7: T2 implicitly overrides T1's, T3 implicitly overrides T1/T2's method +// +// SCENARIO B: T2 has MethodImpl that overrides T1's MethodDecl, WITHOUT any attribute +// ============================================================================== +// Scenario B.1: T3 explicitly overrides T1's MethodDecl +// Scenario B.2: T3 explicitly overrides T2's MethodImpl +// Scenario B.3: T3 implicitly overrides T1's MethodDecl +// Scenario B.4: T3 implicitly overrides T2's MethodImpl +// +// SCENARIO C: T2 has MethodImpl that overrides T1's MethodDecl, WITH the attribute +// ============================================================================== +// Scenario C.1: T3 explicitly overrides T1's MethodDecl +// Scenario C.2: T3 explicitly overrides T2's MethodImpl +// Scenario C.3: T3 implicitly overrides T1's MethodDecl +// Scenario C.4: T3 implicitly overrides T2's MethodImpl +// +// SCENARIO D: T2 implicitly overrides T1's method, WITH the attribute (Attribute treated as NOP) +// ============================================================================== +// Scenario D.1: T3 explicitly overrides T1's method +// Scenario D.2: T3 explicitly overrides T2's method +// Scenario D.3: T3 implicitly overrides T1/T2's method +// +// SCENARIO E: T2 implicitly overrides T1's method, WITHOUT the attribute +// ============================================================================== +// Scenario E.1: T3 explicitly overrides T1's method +// Scenario E.2: T3 explicitly overrides T2's method +// Scenario E.3: T3 implicitly overrides T1/T2's method +// + +// Scenario A +.namespace A +{ + .class public auto ansi beforefieldinit T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance string Func1() + { + .custom instance void [CoreTestAssembly]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + ldstr "T1" + ret + } + } + .class public auto ansi beforefieldinit T2Exp extends A.T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func2() + { + .override method instance string class A.T1::Func1() + ldstr "T2" + ret + } + } + .class public auto ansi beforefieldinit T2Imp extends A.T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func1() + { + ldstr "T2" + ret + } + } + + // Scenario A.1: T2 explicitly overrides T1's, T3 explicitly overrides T1's MethodDecl + .class public auto ansi beforefieldinit T3_1 extends A.T2Exp + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class A.T1::Func1() + ldstr "T3" + ret + } + } + // Scenario A.2: T2 explicitly overrides T1's, T3 explicitly overrides T2's MethodImpl + .class public auto ansi beforefieldinit T3_2 extends A.T2Exp + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class A.T2Exp::Func2() + ldstr "T3" + ret + } + } + + // Scenario A.3: T2 explicitly overrides T1's, T3 implicitly overrides T1's MethodDecl + .class public auto ansi beforefieldinit T3_3 extends A.T2Exp + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func1() + { + ldstr "T3" + ret + } + } + + // Scenario A.4: T2 explicitly overrides T1's, T3 implicitly overrides T2's MethodImpl + .class public auto ansi beforefieldinit T3_4 extends A.T2Exp + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func2() + { + ldstr "T3" + ret + } + } + + // Scenario A.5: T2 implicitly overrides T1's, T3 explicitly overrides T1's method + .class public auto ansi beforefieldinit T3_5 extends A.T2Imp + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class A.T1::Func1() + ldstr "T3" + ret + } + } + + // Scenario A.6: T2 implicitly overrides T1's, T3 explicitly overrides T2's method + .class public auto ansi beforefieldinit T3_6 extends A.T2Imp + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class A.T2Imp::Func1() + ldstr "T3" + ret + } + } + + // Scenario A.7: T2 implicitly overrides T1's, T3 implicitly overrides T1/T2's method + .class public auto ansi beforefieldinit T3_7 extends A.T2Imp + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func1() + { + ldstr "T3" + ret + } + } +} + +// Scenario B +.namespace B +{ + .class public auto ansi beforefieldinit T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func1() + { + ldstr "T1" + ret + } + } + .class public auto ansi beforefieldinit T2 extends B.T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func2() + { + .override method instance string class B.T1::Func1() + ldstr "T2" + ret + } + } + + // Scenario B.1: T3 explicitly overrides T1's MethodDecl + .class public auto ansi beforefieldinit T3_1 extends B.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class B.T1::Func1() + ldstr "T3" + ret + } + } + + // Scenario B.2: T3 explicitly overrides T2's MethodImpl + .class public auto ansi beforefieldinit T3_2 extends B.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class B.T2::Func2() + ldstr "T3" + ret + } + } + + // Scenario B.3: T3 implicitly overrides T1's MethodDecl + .class public auto ansi beforefieldinit T3_3 extends B.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func1() + { + ldstr "T3" + ret + } + } + + // Scenario B.4: T3 implicitly overrides T2's MethodImpl + .class public auto ansi beforefieldinit T3_4 extends B.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func2() + { + ldstr "T3" + ret + } + } +} + +// Scenario C +.namespace C +{ + .class public auto ansi beforefieldinit T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func1() + { + ldstr "T1" + ret + } + } + .class public auto ansi beforefieldinit T2 extends C.T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func2() + { + .custom instance void [CoreTestAssembly]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance string class C.T1::Func1() + ldstr "T2" + ret + } + } + + // Scenario C.1: T3 explicitly overrides T1's MethodDecl + .class public auto ansi beforefieldinit T3_1 extends C.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class C.T1::Func1() + ldstr "T3" + ret + } + } + + // Scenario C.2: T3 explicitly overrides T2's MethodImpl + .class public auto ansi beforefieldinit T3_2 extends C.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class C.T2::Func2() + ldstr "T3" + ret + } + } + + // Scenario C.3: T3 implicitly overrides T1's MethodDecl + .class public auto ansi beforefieldinit T3_3 extends C.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func1() + { + ldstr "T3" + ret + } + } + + // Scenario C.4: T3 implicitly overrides T2's MethodImpl + .class public auto ansi beforefieldinit T3_4 extends C.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func2() + { + ldstr "T3" + ret + } + } +} + +// Scenario D +.namespace D +{ + .class public auto ansi beforefieldinit T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func1() + { + ldstr "T1" + ret + } + } + .class public auto ansi beforefieldinit T2 extends D.T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func1() + { + .custom instance void [CoreTestAssembly]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + ldstr "T2" + ret + } + } + + // Scenario D.1: T3 explicitly overrides T1's method + .class public auto ansi beforefieldinit T3_1 extends D.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class D.T1::Func1() + ldstr "T3" + ret + } + } + + // Scenario D.2: T3 explicitly overrides T2's method + .class public auto ansi beforefieldinit T3_2 extends D.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class D.T2::Func1() + ldstr "T3" + ret + } + } + + // Scenario D.3: T3 implicitly overrides T1/T2's method + .class public auto ansi beforefieldinit T3_3 extends D.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func1() + { + ldstr "T3" + ret + } + } +} + +// Scenario E +.namespace E +{ + .class public auto ansi beforefieldinit T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func1() + { + ldstr "T1" + ret + } + } + .class public auto ansi beforefieldinit T2 extends E.T1 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func1() + { + ldstr "T2" + ret + } + } + + // Scenario E.1: T3 explicitly overrides T1's method + .class public auto ansi beforefieldinit T3_1 extends E.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class E.T1::Func1() + ldstr "T3" + ret + } + } + + // Scenario E.2: T3 explicitly overrides T2's method + .class public auto ansi beforefieldinit T3_2 extends E.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance string Func3() + { + .override method instance string class E.T2::Func1() + ldstr "T3" + ret + } + } + + // Scenario E.3: T3 implicitly overrides T1/T2's method + .class public auto ansi beforefieldinit T3_3 extends E.T2 + { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig virtual instance string Func1() + { + ldstr "T3" + ret + } + } +} +/* +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method private hidebysig static bool CheckResult (string expected,string actual) cil managed + { + // Method begins at RVA 0x217c + // Code size 45 (0x2d) + .maxstack 8 + + // Console.WriteLine("EXPECTED: " + expected); + IL_0000: ldstr " EXPECTED: " + IL_0005: ldarg.0 + IL_0006: call string [CoreTestAssembly]System.String::Concat(string, string) + IL_000b: call void [System.Console]System.Console::WriteLine(string) + // Console.WriteLine("ACTUAL : " + actual); + IL_0010: ldstr " ACTUAL : " + IL_0015: ldarg.1 + IL_0016: call string [CoreTestAssembly]System.String::Concat(string, string) + IL_001b: call void [System.Console]System.Console::WriteLine(string) + // Console.WriteLine(); + IL_0020: call void [System.Console]System.Console::WriteLine() + // return expected == actual; + IL_0025: ldarg.0 + IL_0026: ldarg.1 + IL_0027: call bool [CoreTestAssembly]System.String::op_Equality(string, string) + // (no C# code) + IL_002c: ret + } // end of method Program::CheckResult + + + // =================================================== + + .method private hidebysig static bool ScenarioA_Test1 () cil managed + { + ldstr "ScenarioA_Test1" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void A.T3_1::.ctor() + callvirt instance string class A.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T2" + newobj instance void A.T3_1::.ctor() + callvirt instance string A.T2Exp::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_1::.ctor() + callvirt instance string A.T3_1::Func3() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioA_Test2 () cil managed + { + ldstr "ScenarioA_Test2" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void A.T3_2::.ctor() + callvirt instance string class A.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_2::.ctor() + callvirt instance string A.T2Exp::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_2::.ctor() + callvirt instance string A.T3_2::Func3() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioA_Test3 () cil managed + { + ldstr "ScenarioA_Test3" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void A.T3_3::.ctor() + callvirt instance string class A.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T2" + newobj instance void A.T3_3::.ctor() + callvirt instance string A.T2Exp::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_3::.ctor() + callvirt instance string A.T3_3::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioA_Test4 () cil managed + { + ldstr "ScenarioA_Test4" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void A.T3_4::.ctor() + callvirt instance string class A.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_4::.ctor() + callvirt instance string A.T2Exp::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_4::.ctor() + callvirt instance string A.T3_4::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioA_Test5 () cil managed + { + ldstr "ScenarioA_Test5" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void A.T3_5::.ctor() + callvirt instance string class A.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_5::.ctor() + callvirt instance string A.T2Imp::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_5::.ctor() + callvirt instance string A.T3_5::Func3() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioA_Test6 () cil managed + { + ldstr "ScenarioA_Test6" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void A.T3_6::.ctor() + callvirt instance string class A.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_6::.ctor() + callvirt instance string A.T2Imp::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_6::.ctor() + callvirt instance string A.T3_6::Func3() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioA_Test7 () cil managed + { + ldstr "ScenarioA_Test7" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void A.T3_7::.ctor() + callvirt instance string class A.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_7::.ctor() + callvirt instance string A.T2Imp::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void A.T3_7::.ctor() + callvirt instance string A.T3_7::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + // =================================================== + + .method private hidebysig static bool ScenarioB_Test1 () cil managed + { + ldstr "ScenarioB_Test1" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void B.T3_1::.ctor() + callvirt instance string class B.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T2" + newobj instance void B.T3_1::.ctor() + callvirt instance string B.T2::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void B.T3_1::.ctor() + callvirt instance string B.T3_1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioB_Test2 () cil managed + { + ldstr "ScenarioB_Test2" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void B.T3_2::.ctor() + callvirt instance string class B.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void B.T3_2::.ctor() + callvirt instance string B.T2::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void B.T3_2::.ctor() + callvirt instance string B.T3_2::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioB_Test3 () cil managed + { + ldstr "ScenarioB_Test3" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void B.T3_3::.ctor() + callvirt instance string class B.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T2" + newobj instance void B.T3_3::.ctor() + callvirt instance string B.T2::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void B.T3_3::.ctor() + callvirt instance string B.T3_3::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioB_Test4 () cil managed + { + ldstr "ScenarioB_Test4" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void B.T3_4::.ctor() + callvirt instance string class B.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void B.T3_4::.ctor() + callvirt instance string B.T2::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void B.T3_4::.ctor() + callvirt instance string B.T3_4::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void B.T3_4::.ctor() + callvirt instance string B.T3_4::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + // =================================================== + + .method private hidebysig static bool ScenarioC_Test1 () cil managed + { + ldstr "ScenarioC_Test1" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void C.T3_1::.ctor() + callvirt instance string class C.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void C.T3_1::.ctor() + callvirt instance string C.T2::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void C.T3_1::.ctor() + callvirt instance string C.T3_1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioC_Test2 () cil managed + { + ldstr "ScenarioC_Test2" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void C.T3_2::.ctor() + callvirt instance string class C.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void C.T3_2::.ctor() + callvirt instance string C.T2::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void C.T3_2::.ctor() + callvirt instance string C.T3_2::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioC_Test3 () cil managed + { + ldstr "ScenarioC_Test3" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void C.T3_3::.ctor() + callvirt instance string class C.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T2" + newobj instance void C.T3_3::.ctor() + callvirt instance string C.T2::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void C.T3_3::.ctor() + callvirt instance string C.T3_3::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioC_Test4 () cil managed + { + ldstr "ScenarioC_Test4" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void C.T3_4::.ctor() + callvirt instance string class C.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void C.T3_4::.ctor() + callvirt instance string C.T2::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void C.T3_4::.ctor() + callvirt instance string C.T3_4::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void C.T3_4::.ctor() + callvirt instance string C.T3_4::Func2() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + // =================================================== + + .method private hidebysig static bool ScenarioD_Test1 () cil managed + { + ldstr "ScenarioD_Test1" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void D.T3_1::.ctor() + callvirt instance string class D.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void D.T3_1::.ctor() + callvirt instance string D.T2::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void D.T3_1::.ctor() + callvirt instance string D.T3_1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void D.T3_1::.ctor() + callvirt instance string D.T3_1::Func3() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioD_Test2 () cil managed + { + ldstr "ScenarioD_Test2" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void D.T3_2::.ctor() + callvirt instance string class D.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void D.T3_2::.ctor() + callvirt instance string D.T2::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void D.T3_2::.ctor() + callvirt instance string D.T3_2::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void D.T3_1::.ctor() + callvirt instance string D.T3_1::Func3() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioD_Test3 () cil managed + { + ldstr "ScenarioD_Test3" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void D.T3_3::.ctor() + callvirt instance string class D.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void D.T3_3::.ctor() + callvirt instance string D.T2::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void D.T3_3::.ctor() + callvirt instance string D.T3_3::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + // =================================================== + + .method private hidebysig static bool ScenarioE_Test1 () cil managed + { + ldstr "ScenarioE_Test1" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void E.T3_1::.ctor() + callvirt instance string class E.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void E.T3_1::.ctor() + callvirt instance string E.T2::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void E.T3_1::.ctor() + callvirt instance string E.T3_1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void E.T3_1::.ctor() + callvirt instance string E.T3_1::Func3() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioE_Test2 () cil managed + { + ldstr "ScenarioE_Test2" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void E.T3_2::.ctor() + callvirt instance string class E.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void E.T3_2::.ctor() + callvirt instance string E.T2::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void E.T3_2::.ctor() + callvirt instance string E.T3_2::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void E.T3_1::.ctor() + callvirt instance string E.T3_1::Func3() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method private hidebysig static bool ScenarioE_Test3 () cil managed + { + ldstr "ScenarioE_Test3" + call void [System.Console]System.Console::WriteLine(string) + + ldstr "T3" + newobj instance void E.T3_3::.ctor() + callvirt instance string class E.T1::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void E.T3_3::.ctor() + callvirt instance string E.T2::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldstr "T3" + newobj instance void E.T3_3::.ctor() + callvirt instance string E.T3_3::Func1() + call bool CMain::CheckResult(string, string) + brfalse.s FAILED + + ldc.i4.1 + ret + FAILED: + ldc.i4.0 + ret + } + + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + // ==================================================== // + + ldloc.0 + call bool CMain::ScenarioA_Test1() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioA_Test2() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioA_Test3() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioA_Test4() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioA_Test5() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioA_Test6() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioA_Test7() + and + stloc.0 + + // ==================================================== // + + ldloc.0 + call bool CMain::ScenarioB_Test1() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioB_Test2() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioB_Test3() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioB_Test4() + and + stloc.0 + + // ==================================================== // + + ldloc.0 + call bool CMain::ScenarioC_Test1() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioC_Test2() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioC_Test3() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioC_Test4() + and + stloc.0 + + // ==================================================== // + + ldloc.0 + call bool CMain::ScenarioD_Test1() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioD_Test2() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioD_Test3() + and + stloc.0 + + // ==================================================== // + + ldloc.0 + call bool CMain::ScenarioE_Test1() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioE_Test2() + and + stloc.0 + + ldloc.0 + call bool CMain::ScenarioE_Test3() + and + stloc.0 + + // ==================================================== // + + DONE: + ldloc.0 + brtrue.s PASS + + ldstr "Test FAILED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + + ldc.i4.s 100 + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } +} +*/ \ No newline at end of file diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/VirtualFunctionOverrideTests.cs b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/VirtualFunctionOverrideTests.cs index d2f9d9576c631..25adae65bda26 100644 --- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/VirtualFunctionOverrideTests.cs +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/VirtualFunctionOverrideTests.cs @@ -3,10 +3,14 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; +using System.Reflection; +using Internal.IL; using Internal.TypeSystem; - +using Internal.TypeSystem.Ecma; using Xunit; +using Xunit.Abstractions; namespace TypeSystemTests @@ -17,9 +21,11 @@ public class VirtualFunctionOverrideTests private ModuleDesc _testModule; private DefType _stringType; private DefType _voidType; + private ITestOutputHelper _logger; - public VirtualFunctionOverrideTests() + public VirtualFunctionOverrideTests(ITestOutputHelper logger) { + _logger = logger; _context = new TestTypeSystemContext(TargetArchitecture.X64); var systemModule = _context.CreateModuleForSimpleName("CoreTestAssembly"); _context.SetSystemModule(systemModule); @@ -289,5 +295,179 @@ public void TestFunctionPointerOverloads() Assert.Equal(expectedMethods[0].Signature[0], expectedMethods[1].Signature[0]); Assert.NotEqual(expectedMethods[0].Signature[0], expectedMethods[3].Signature[0]); } + + [Theory] + // ScenarioA_Test1 + [InlineData("ScenarioA_Test1_1", "T3", "A.T3_1", "A.T1", "Func1")] + [InlineData("ScenarioA_Test1_2", "T2", "A.T3_1", "A.T2Exp", "Func2")] + [InlineData("ScenarioA_Test1_3", "T3", "A.T3_1", "A.T3_1", "Func3")] + + // ScenarioA_Test2 + [InlineData("ScenarioA_Test2_1", "T3", "A.T3_2", "A.T1", "Func1")] + [InlineData("ScenarioA_Test2_2", "T3", "A.T3_2", "A.T2Exp", "Func2")] + [InlineData("ScenarioA_Test2_3", "T3", "A.T3_2", "A.T3_2", "Func3")] + + // ScenarioA_Test3 + [InlineData("ScenarioA_Test3_1", "T3", "A.T3_3", "A.T1", "Func1")] + [InlineData("ScenarioA_Test3_2", "T2", "A.T3_3", "A.T2Exp", "Func2")] + [InlineData("ScenarioA_Test3_3", "T3", "A.T3_3", "A.T3_3", "Func1")] + + // ScenarioA_Test4 + [InlineData("ScenarioA_Test4_1", "T3", "A.T3_4", "A.T1", "Func1")] + [InlineData("ScenarioA_Test4_2", "T3", "A.T3_4", "A.T2Exp", "Func2")] + [InlineData("ScenarioA_Test4_3", "T3", "A.T3_4", "A.T3_4", "Func2")] + + // ScenarioA_Test5 + [InlineData("ScenarioA_Test5_1", "T3", "A.T3_5", "A.T1", "Func1")] + [InlineData("ScenarioA_Test5_2", "T3", "A.T3_5", "A.T2Imp", "Func1")] + [InlineData("ScenarioA_Test5_3", "T3", "A.T3_5", "A.T3_5", "Func3")] + + // ScenarioA_Test6 + [InlineData("ScenarioA_Test6_1", "T3", "A.T3_6", "A.T1", "Func1")] + [InlineData("ScenarioA_Test6_2", "T3", "A.T3_6", "A.T2Imp", "Func1")] + [InlineData("ScenarioA_Test6_3", "T3", "A.T3_6", "A.T3_6", "Func3")] + + // ScenarioA_Test7 + [InlineData("ScenarioA_Test7_1", "T3", "A.T3_7", "A.T1", "Func1")] + [InlineData("ScenarioA_Test7_2", "T3", "A.T3_7", "A.T2Imp", "Func1")] + [InlineData("ScenarioA_Test7_3", "T3", "A.T3_7", "A.T3_7", "Func1")] + + // ScenarioB_Test1 + [InlineData("ScenarioB_Test_1_1", "T3", "B.T3_1", "B.T1", "Func1")] + [InlineData("ScenarioB_Test_1_2", "T2", "B.T3_1", "B.T2", "Func2")] + [InlineData("ScenarioB_Test_1_3", "T3", "B.T3_1", "B.T3_1", "Func3")] // Change from IL + + // ScenarioB_Test2 + [InlineData("ScenarioB_Test_2_1", "T3", "B.T3_2", "B.T1", "Func1")] + [InlineData("ScenarioB_Test_2_2", "T3", "B.T3_2", "B.T2", "Func2")] + [InlineData("ScenarioB_Test_2_3", "T3", "B.T3_2", "B.T3_2", "Func3")] // Change from IL + + // ScenarioB_Test3 + [InlineData("ScenarioB_Test_3_1", "T3", "B.T3_3", "B.T1", "Func1")] + [InlineData("ScenarioB_Test_3_2", "T2", "B.T3_3", "B.T2", "Func2")] + [InlineData("ScenarioB_Test_3_3", "T3", "B.T3_3", "B.T3_3", "Func1")] + + // ScenarioB_Test4 + [InlineData("ScenarioB_Test_4_1", "T3", "B.T3_4", "B.T1", "Func1")] + [InlineData("ScenarioB_Test_4_2", "T3", "B.T3_4", "B.T2", "Func2")] + [InlineData("ScenarioB_Test_4_3", "T3", "B.T3_4", "B.T3_4", "Func2")] // Change from IL + + // ScenarioC_Test1 + [InlineData("ScenarioC_Test_1_1", "T3", "C.T3_1", "C.T1", "Func1")] + [InlineData("ScenarioC_Test_1_2", "T3", "C.T3_1", "C.T2", "Func2")] + [InlineData("ScenarioC_Test_1_3", "T3", "C.T3_1", "C.T3_1", "Func3")] + + // ScenarioC_Test2 + [InlineData("ScenarioC_Test_2_1", "T3", "C.T3_2", "C.T1", "Func1")] + [InlineData("ScenarioC_Test_2_2", "T3", "C.T3_2", "C.T2", "Func2")] + [InlineData("ScenarioC_Test_2_3", "T3", "C.T3_2", "C.T3_2", "Func3")] // Change from IL + + // ScenarioC_Test3 + [InlineData("ScenarioC_Test_3_1", "T3", "C.T3_3", "C.T1", "Func1")] + [InlineData("ScenarioC_Test_3_2", "T2", "C.T3_3", "C.T2", "Func2")] + [InlineData("ScenarioC_Test_3_3", "T3", "C.T3_3", "C.T3_3", "Func1")] + + // ScenarioC_Test4 + [InlineData("ScenarioC_Test_4_1", "T3", "C.T3_4", "C.T1", "Func1")] + [InlineData("ScenarioC_Test_4_2", "T3", "C.T3_4", "C.T2", "Func2")] + [InlineData("ScenarioC_Test_4_3", "T3", "C.T3_4", "C.T3_4", "Func2")] // Change from IL + [InlineData("ScenarioC_Test_4_4", "T3", "C.T3_4", "C.T3_4", "Func2")] + + // ScenarioD_Test1 + [InlineData("ScenarioD_Test_1_1", "T3", "D.T3_1", "D.T1", "Func1")] + [InlineData("ScenarioD_Test_1_2", "T3", "D.T3_1", "D.T2", "Func1")] + [InlineData("ScenarioD_Test_1_3", "T3", "D.T3_1", "D.T3_1", "Func3")] // Change from IL + [InlineData("ScenarioD_Test_1_4", "T3", "D.T3_1", "D.T3_1", "Func3")] + + // ScenarioD_Test2 + [InlineData("ScenarioD_Test_2_1", "T3", "D.T3_2", "D.T1", "Func1")] + [InlineData("ScenarioD_Test_2_2", "T3", "D.T3_2", "D.T2", "Func1")] + [InlineData("ScenarioD_Test_2_3", "T3", "D.T3_2", "D.T3_2", "Func3")] // Change from IL + // DUPLICATE?!?! [InlineData("T3", "D.T3_1", "D.T3_1", "Func3")] + + // ScenarioD_Test3 + [InlineData("ScenarioD_Test_3_1", "T3", "D.T3_3", "D.T1", "Func1")] + [InlineData("ScenarioD_Test_3_2", "T3", "D.T3_3", "D.T2", "Func1")] + [InlineData("ScenarioD_Test_3_3", "T3", "D.T3_3", "D.T3_3", "Func1")] + + // ScenarioE_Test1 + [InlineData("ScenarioE_Test_1_1", "T3", "E.T3_1", "E.T1", "Func1")] + [InlineData("ScenarioE_Test_1_2", "T3", "E.T3_1", "E.T2", "Func1")] + [InlineData("ScenarioE_Test_1_3", "T3", "E.T3_1", "E.T3_1", "Func3")] + + // ScenarioE_Test2 + [InlineData("ScenarioE_Test_2_1", "T3", "E.T3_2", "E.T1", "Func1")] + [InlineData("ScenarioE_Test_2_2", "T3", "E.T3_2", "E.T2", "Func1")] + [InlineData("ScenarioE_Test_2_3", "T3", "E.T3_2", "E.T3_2", "Func3")] + // DUPLICATE?!?!? [InlineData("T3", "E.T3_1", "E.T3_1", "Func3")] + + // ScenarioE_Test3 + [InlineData("ScenarioE_Test_3_1", "T3", "E.T3_3", "E.T1", "Func1")] + [InlineData("ScenarioE_Test_3_2", "T3", "E.T3_3", "E.T2", "Func1")] + [InlineData("ScenarioE_Test_3_3", "T3", "E.T3_3", "E.T3_3", "Func1")] + public void TestPreserveBaseOverridesBehavior(string exactScenarioName, string stringToExpect, string typeToConstruct, string typeOfMethodToCallOn, string methodName) + { + this._logger.WriteLine(exactScenarioName); + var ilModule = _context.GetModuleForSimpleName("ILTestAssembly"); + (string typeToConstructNamespace, string typeToConstructTypeName) = SplitIntoNameAndNamespace(typeToConstruct); + var constructedType = ilModule.GetType(typeToConstructNamespace, typeToConstructTypeName); + + (string typeToCallNamespace, string typeToCallTypeName) = SplitIntoNameAndNamespace(typeOfMethodToCallOn); + var typeToCall = ilModule.GetType(typeToCallNamespace, typeToCallTypeName); + + MethodDesc callMethod = typeToCall.GetMethod(methodName, null); + Assert.NotNull(callMethod); + + MethodDesc resolvedMethod = constructedType.FindVirtualFunctionTargetMethodOnObjectType(callMethod); + + var methodIL = Internal.IL.EcmaMethodIL.Create((EcmaMethod)resolvedMethod); + ILReader reader = new ILReader(methodIL.GetILBytes()); + Assert.Equal(ILOpcode.ldstr, reader.ReadILOpcode()); + + int userStringToken = reader.ReadILToken(); + string stringLoadedAsFirstILOpcodeInResolvedMethod = (string)methodIL.GetObject(userStringToken); + Assert.Equal(stringToExpect, stringLoadedAsFirstILOpcodeInResolvedMethod); + } + + + [Theory] + [InlineData("Base", "BaseCovariant")] + [InlineData("Impl", "ImplCovariant")] + [InlineData("SubImpl", "SubImplCovariant")] + [InlineData("SubImpl_OverrideViaNameSig", "SubImplCovariant2")] + [InlineData("SubImpl_OverrideViaNameSig_OverridenViaMethodImpl", "SubSubImplCovariant")] + public void TestSubImplCovariant(string exactScenarioName, string typeToConstruct) + { + this._logger.WriteLine(exactScenarioName); + + MetadataType derivedClass = _testModule.GetType("VirtualFunctionOverride", typeToConstruct); + MetadataType baseClass = derivedClass; + + while (baseClass != baseClass.Context.GetWellKnownType(WellKnownType.Object)) + { + this._logger.WriteLine("-----"); + this._logger.WriteLine(baseClass.ToString()); + MethodDesc callMethod = baseClass.GetMethod("FromType", null); + this._logger.WriteLine(callMethod.ToString()); + Assert.NotNull(callMethod); + + MethodDesc resolvedMethod = derivedClass.FindVirtualFunctionTargetMethodOnObjectType(callMethod); + this._logger.WriteLine(resolvedMethod.ToString()); + + Assert.Equal(typeToConstruct, ((EcmaType)((EcmaMethod)resolvedMethod).OwningType).Name); + + baseClass = (MetadataType)baseClass.BaseType; + } + } + + private static (string _namespace, string type) SplitIntoNameAndNamespace(string typeName) + { + int namespaceIndextypeName = typeName.LastIndexOf('.'); + Assert.True(namespaceIndextypeName > 0); + string typeNameNamespace = typeName.Substring(0, namespaceIndextypeName); + string typeNameTypeName = typeName.Substring(namespaceIndextypeName + 1); + Assert.True(typeNameTypeName.Length > 0); + return (typeNameNamespace, typeNameTypeName); + } } } diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il index cc85b79accf01..504c56b2d28d9 100644 --- a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il @@ -438,55 +438,6 @@ } } - -// ======================================================================================== -// FIFTH LAYER INVALID type: Used to verify we can't override the method using a compatible interface -// if it has been already overridden using a class that implements the interface (i.e. the new -// interface return type won't be compatible with the class return type on the previous override -// ======================================================================================== - -.class public auto ansi beforefieldinit Invalid1 extends class GenMoreDerived -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } - - .method public hidebysig newslot virtual instance class INonGenThroughGen4 NonGenThroughGenFunc(string& res) - { - .override method instance class IB class GenBaseType::NonGenThroughGenFunc(string& res) - ldnull - ret - } -} - -// ======================================================================================== -// FIFTH LAYER INVALID type: Used to verify we can't override the method using a less derived interface -// than one that has already been used in a previous override -// ======================================================================================== - -.class public auto ansi beforefieldinit Invalid2 extends class GenTestType -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } - - .method public hidebysig newslot virtual instance class INonGenThroughGen2 NonGenThroughGenFunc(string& res) - { - .override method instance class IB class GenBaseType::NonGenThroughGenFunc(string& res) - ldnull - ret - } -} - -.class public auto ansi beforefieldinit Invalid3 extends class GenTestType -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } - - .method public hidebysig newslot virtual instance class IVariant MultiLevelGenericVariantFunc(string&) - { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) - .override method instance class IVariant> class GenBaseType::MultiLevelGenericVariantFunc(string&) - ldnull - ret - } -} - // ======================================================================================== .class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object @@ -1110,30 +1061,6 @@ ret } - - // ===================================================================================== // - - .method public static void RunTest_Invalid1() noinlining - { - newobj instance void class Invalid1::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest_Invalid2() noinlining - { - newobj instance void class Invalid2::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest_Invalid3() noinlining - { - newobj instance void class Invalid3::.ctor() - callvirt instance class IVariant class Invalid3::MultiLevelGenericVariantFunc() - pop - ret - } // ===================================================================================== // .method public hidebysig static int32 Main() cil managed @@ -1262,68 +1189,12 @@ MOREDERIVED6: call bool CMain::RunTest_MoreDerived6() - brtrue.s INVALID1 + brtrue.s DONE ldc.i4.0 stloc.0 // ===================================================================================== // - INVALID1: - .try - { - call void CMain::RunTest_Invalid1() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid1." - call void [System.Console]System.Console::WriteLine(string) - leave.s INVALID2 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s INVALID2 - } - - INVALID2: - .try - { - call void CMain::RunTest_Invalid2() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid2." - call void [System.Console]System.Console::WriteLine(string) - leave.s INVALID3 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s INVALID3 - } - - INVALID3: - .try - { - call void CMain::RunTest_Invalid3() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading DerivedClassFail1." - call void [System.Console]System.Console::WriteLine(string) - leave.s DONE - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s DONE - } - - // ===================================================================================== // - DONE: ldloc.0 brtrue.s PASS diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest_TypeLoadException.il b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest_TypeLoadException.il new file mode 100644 index 0000000000000..88a72b70ec025 --- /dev/null +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest_TypeLoadException.il @@ -0,0 +1,609 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +.assembly extern System.Console { } +.assembly extern xunit.core {} +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly UnitTest_TypeLoadException { } + +// ======================================================================================== +// Types that will be used as return types on the various methods +// ======================================================================================== + +.class interface public auto ansi abstract IUnused1 { } +.class interface public auto ansi abstract IUnused2 { } + +.class interface public auto ansi abstract IA implements IUnused1, IUnused2 { } +.class interface public auto ansi abstract IB implements IUnused1, IUnused2, IA { } +.class interface public auto ansi abstract IC implements IUnused1, IUnused2, IB { } + +.class interface public auto ansi abstract IGenRetType { } +.class interface public auto ansi abstract IDictionary { } + +.class public auto ansi abstract CA {} +.class public auto ansi abstract CB extends CA {} +.class public auto ansi abstract CC extends CB {} + +.class interface public auto ansi abstract ICovariant<+ T> { } +.class interface public auto ansi abstract IContravariant<- T> { } + +.class interface public auto ansi abstract IGenDerive1 implements IUnused1, IUnused2, class IGenRetType { } +.class interface public auto ansi abstract IGenDerive2 implements IUnused1, IUnused2, class IGenDerive1> { } +.class interface public auto ansi abstract IGenDerive3 implements IUnused1, IUnused2, class IGenDerive2 { } + +.class interface public auto ansi abstract INonGenericDerived1 implements IUnused1, IUnused2, class IGenRetType { } +.class interface public auto ansi abstract INonGenericDerived2 implements IUnused1, IUnused2, class INonGenericDerived1 { } +.class interface public auto ansi abstract INonGenericDerived3 implements IUnused1, IUnused2, class INonGenericDerived2 { } +.class interface public auto ansi abstract INonGenericDerived4 implements IUnused1, IUnused2, INonGenericDerived3 { } + +.class interface public auto ansi abstract IGenToNonGen1 implements IUnused1, IUnused2, IC { } +.class interface public auto ansi abstract IGenToNonGen2 implements IUnused1, IUnused2, class IGenToNonGen1> { } +.class interface public auto ansi abstract IGenToNonGen3 implements IUnused1, IUnused2, class IGenToNonGen2 { } + +.class interface public auto ansi abstract INonGenThroughGen1 implements IUnused1, IUnused2, IC { } +.class interface public auto ansi abstract INonGenThroughGen2 implements IUnused1, IUnused2, class INonGenThroughGen1> { } +.class interface public auto ansi abstract INonGenThroughGen3 implements IUnused1, IUnused2, class INonGenThroughGen2 { } +.class interface public auto ansi abstract INonGenThroughGen4 implements IUnused1, IUnused2, INonGenThroughGen3 { } + +// class implementing the interfaces +.class public auto ansi beforefieldinit NonGenThroughGen4 implements IUnused1, IUnused2, INonGenThroughGen4 { } +.class public auto ansi beforefieldinit GenToNonGen3 implements IUnused1, IUnused2, class IGenToNonGen3 { } +.class public auto ansi beforefieldinit NonGenericDerived4 implements IUnused1, IUnused2, INonGenericDerived4 { } +.class public auto ansi beforefieldinit GenDerive3 implements IUnused1, IUnused2, class IGenDerive3 { } +.class public auto ansi beforefieldinit C implements IUnused1, IUnused2, IC { } +.class public auto ansi beforefieldinit GenRetType implements IUnused1, IUnused2, class IGenRetType { } + +.class public auto ansi beforefieldinit Base {} +.class public auto ansi beforefieldinit Derived extends class Base {} +.class public auto ansi beforefieldinit Derived2 extends class Base {} + +.class interface public auto ansi abstract IVariant<+ V> +{ + .method public hidebysig newslot virtual instance void Test() + { + ret + } +} + +// ======================================================================================== +// Main base type with various virtual methods that will be overridden later +// ======================================================================================== + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance object MyFunc(string& res) + { + ldarg.1 + ldstr "object GenBaseType.MyFunc()" + stind.ref + ldnull + ret + } + .method public hidebysig newslot virtual instance class IB MyFunc(string& res) + { + ldarg.1 + ldstr "IB GenBaseType.MyFunc()" + stind.ref + ldnull + ret + } + .method public hidebysig newslot virtual instance class ICovariant MyFuncCovariant(string& res) + { + ldarg.1 + ldstr "ICovariant GenBaseType.MyFuncCovariant()" + stind.ref + ldnull + ret + } + .method public hidebysig newslot virtual instance class IContravariant MyFuncContravariant(string& res) + { + ldarg.1 + ldstr "IContravariant GenBaseType.MyFuncContravariant()" + stind.ref + ldnull + ret + } + .method public hidebysig newslot virtual instance class IB GenToNonGen(string& res) + { + ldarg.1 + ldstr "IB GenBaseType.GenToNonGen()" + stind.ref + ldnull + ret + } + .method public hidebysig newslot virtual instance class IB NonGenThroughGenFunc(string& res) + { + ldarg.1 + ldstr "IB GenBaseType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + .method public hidebysig newslot virtual instance class IGenRetType MyGenFunc(string& res) + { + ldarg.1 + ldstr "IGenRetType GenBaseType.MyGenFunc()" + stind.ref + ldnull + ret + } + .method public hidebysig newslot virtual instance class IGenRetType> MyGenFunc(string& res) + { + ldarg.1 + ldstr "IGenRetType> GenBaseType.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class IVariant> MultiLevelGenericVariantFunc(string&) + { + ldarg.1 + ldstr "IVariant> GenBaseType.MultiLevelGenericVariantFunc()" + stind.ref + ldnull + ret + } +} + +// ======================================================================================== +// SECOND LAYER type: overrides *SOME* virtuals on GenBaseType using MethodImpls with +// covariant return types (more derived return types) +// ======================================================================================== + +.class public auto ansi beforefieldinit GenMiddleType extends class GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class INonGenThroughGen2 NonGenThroughGenFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class IB class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "INonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class IGenToNonGen1> GenToNonGen(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class IB class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "IGenToNonGen1> GenMiddleType.GenToNonGen()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class INonGenericDerived1 MyGenFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class IGenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "INonGenericDerived1 GenMiddleType.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class IGenDerive1> MyGenFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class IGenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "IGenDerive1> GenMiddleType.MyGenFunc()" + stind.ref + ldnull + ret + } +} + + +// ======================================================================================== +// THIRD LAYER type: overrides all virtuals from GenBaseType using MethodImpls with +// covariant return types (more derived return types than the ones used in GenMiddleType) +// ======================================================================================== + +.class public auto ansi beforefieldinit GenTestType extends class GenMiddleType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class INonGenThroughGen4 NonGenThroughGenFunc(string& res) + { + .override method instance class IB class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "INonGenThroughGen4 TestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class IGenToNonGen3 GenToNonGen(string& res) + { + .override method instance class IB class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "IGenToNonGen3 TestType.GenToNonGen()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class INonGenericDerived4 MyGenFunc(string& res) + { + .override method instance class IGenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "INonGenericDerived4 TestType.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class IGenDerive3 MyGenFunc(string& res) + { + .override method instance class IGenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "IGenDerive3 TestType.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class IGenRetType MyFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "IGenRetType TestType.MyFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class IC MyFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class IB class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "IC TestType.MyFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class ICovariant MyFuncCovariant(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class ICovariant class GenBaseType::MyFuncCovariant(string& res) + ldarg.1 + ldstr "ICovariant TestType.MyFuncCovariant()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class IContravariant MyFuncContravariant(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class IContravariant class GenBaseType::MyFuncContravariant(string& res) + ldarg.1 + ldstr "IContravariant TestType.MyFuncContravariant()" + stind.ref + ldnull + ret + } + + // ======================================================================================== + // Set of implicit overrides that should be ignored given there are explicit overrides from the MethodImpls + // ======================================================================================== + .method public hidebysig virtual instance class IB NonGenThroughGenFunc(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } + + .method public hidebysig virtual instance class IB GenToNonGen(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } + + .method public hidebysig virtual instance class IGenRetType MyGenFunc(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } + + .method public hidebysig virtual instance class IGenRetType> MyGenFunc(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } + + .method public hidebysig virtual instance object MyFunc(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } + + .method public hidebysig virtual instance class IB MyFunc(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } + + .method public hidebysig virtual instance class ICovariant MyFuncCovariant(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } + + .method public hidebysig virtual instance class IContravariant MyFuncContravariant(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } +} + +// ======================================================================================== +// FOURTH LAYER type: overrides all virtuals from GenBaseType using MethodImpls with +// covariant return types (classes that implement the interfaces used as return types) +// ======================================================================================== + +.class public auto ansi beforefieldinit GenMoreDerived extends class GenTestType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc(string& res) + { + .override method instance class IB class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "class NonGenThroughGen4 GenMoreDerived.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGen(string& res) + { + .override method instance class IB class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "class GenToNonGen3 GenMoreDerived.GenToNonGen()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived4 MyGenFunc(string& res) + { + .override method instance class IGenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "class NonGenericDerived4 GenMoreDerived.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive3 MyGenFunc(string& res) + { + .override method instance class IGenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "class GenDerive3 GenMoreDerived.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenRetType MyFunc(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "class GenRetType GenMoreDerived.MyFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C MyFunc(string& res) + { + .override method instance class IB class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "class C GenMoreDerived.MyFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class IVariant MultiLevelGenericVariantFunc(string&) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class IVariant> class GenBaseType::MultiLevelGenericVariantFunc(string&) + ldarg.1 + ldstr "class IVariant GenMoreDerived.MultiLevelGenericVariantFunc()" + stind.ref + ldnull + ret + } +} + + +// ======================================================================================== +// FIFTH LAYER INVALID type: Used to verify we can't override the method using a compatible interface +// if it has been already overridden using a class that implements the interface (i.e. the new +// interface return type won't be compatible with the class return type on the previous override +// ======================================================================================== + +.class public auto ansi beforefieldinit Invalid1 extends class GenMoreDerived +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class INonGenThroughGen4 NonGenThroughGenFunc(string& res) + { + .override method instance class IB class GenBaseType::NonGenThroughGenFunc(string& res) + ldnull + ret + } +} + +// ======================================================================================== +// FIFTH LAYER INVALID type: Used to verify we can't override the method using a less derived interface +// than one that has already been used in a previous override +// ======================================================================================== + +.class public auto ansi beforefieldinit Invalid2 extends class GenTestType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class INonGenThroughGen2 NonGenThroughGenFunc(string& res) + { + .override method instance class IB class GenBaseType::NonGenThroughGenFunc(string& res) + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Invalid3 extends class GenTestType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class IVariant MultiLevelGenericVariantFunc(string&) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class IVariant> class GenBaseType::MultiLevelGenericVariantFunc(string&) + ldnull + ret + } +} + + // ===================================================================================== // + + .method public static void RunTest_Invalid1() noinlining + { + newobj instance void class Invalid1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest_Invalid2() noinlining + { + newobj instance void class Invalid2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest_Invalid3() noinlining + { + newobj instance void class Invalid3::.ctor() + callvirt instance class IVariant class Invalid3::MultiLevelGenericVariantFunc() + pop + ret + } + // ===================================================================================== // + + .method public hidebysig static int32 Main() cil managed + { + .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( + 01 00 00 00 + ) + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + INVALID1: + .try + { + call void CMain::RunTest_Invalid1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid1." + call void [System.Console]System.Console::WriteLine(string) + leave.s INVALID2 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s INVALID2 + } + + INVALID2: + .try + { + call void CMain::RunTest_Invalid2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid2." + call void [System.Console]System.Console::WriteLine(string) + leave.s INVALID3 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s INVALID3 + } + + INVALID3: + .try + { + call void CMain::RunTest_Invalid3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading DerivedClassFail1." + call void [System.Console]System.Console::WriteLine(string) + leave.s DONE + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s DONE + } + + // ===================================================================================== // + + DONE: + ldloc.0 + brtrue.s PASS + + ldstr "Test FAILED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + + ldc.i4.s 100 + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } +} diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest_TypeLoadException.ilproj b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest_TypeLoadException.ilproj new file mode 100644 index 0000000000000..ef656c0dff17e --- /dev/null +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest_TypeLoadException.ilproj @@ -0,0 +1,9 @@ + + + + true + + + + + diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il index 44e996889de7a..d4a4a64467bae 100644 --- a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il @@ -800,7 +800,7 @@ .try { call void Main::RunTestC1() - leave.s CC2 + leave.s CC3 } catch [mscorlib]System.TypeLoadException { @@ -809,45 +809,9 @@ call void [System.Console]System.Console::WriteLine(object) ldc.i4.0 stloc.0 - leave.s CC2 + leave.s CC3 } -CC2: - ldstr "C2: override int32[] by IList" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC2() - ldc.i4.0 - stloc.0 - leave.s CD2 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CD2 - } -CD2: - ldstr "D2: call non-overriding method MD2 when base class of D2 has invalid covariant override" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestD2() - ldc.i4.0 - stloc.0 - leave.s CC3 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC3 - } CC3: ldstr "C3: override IList by int32[]" call void [System.Console]System.Console::WriteLine(string) @@ -855,7 +819,7 @@ CC3: .try { call void Main::RunTestC3() - leave.s CC4 + leave.s CC6 } catch [mscorlib]System.TypeLoadException { @@ -864,44 +828,6 @@ CC3: call void [System.Console]System.Console::WriteLine(object) ldc.i4.0 stloc.0 - leave.s CC4 - } - -CC4: - ldstr "C4: override int32 by Nullable`1" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC4() - ldc.i4.0 - stloc.0 - leave.s CC5 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC5 - } - -CC5: - ldstr "C5: override Nullable by int32" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC5() - ldc.i4.0 - stloc.0 - leave.s CC6 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) leave.s CC6 } CC6: @@ -947,7 +873,7 @@ CC8: .try { call void Main::RunTestC8() - leave.s CC9 + leave.s CC15 } catch [mscorlib]System.TypeLoadException { @@ -956,114 +882,6 @@ CC8: call void [System.Console]System.Console::WriteLine(object) ldc.i4.0 stloc.0 - leave.s CC9 - } -CC9: - ldstr "C9: override native int[] by uint64[]" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC9() - ldc.i4.0 - stloc.0 - leave.s CC10 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC10 - } -CC10: - ldstr "C10: override native int[] by uint32[]" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC10() - ldc.i4.0 - stloc.0 - leave.s CC11 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC11 - } -CC11: - ldstr "C11: override Base* by Derived*" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC11() - ldc.i4.0 - stloc.0 - leave.s CC12 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC12 - } -CC12: - ldstr "C12: override void* by int32*" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC12() - ldc.i4.0 - stloc.0 - leave.s CC13 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC13 - } -CC13: - ldstr "C13: override int32 *(class Base) by int32 *(class Derived)" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC13() - ldc.i4.0 - stloc.0 - leave.s CC14 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC14 - } -CC14: - ldstr "C14: override int32 *(class Base) by int32 *(class C1)" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC14() - ldc.i4.0 - stloc.0 - leave.s CC15 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) leave.s CC15 } CC15: @@ -1127,7 +945,7 @@ CC18: .try { call void Main::RunTestC18() - leave.s CC19 + leave.s CC20 } catch [mscorlib]System.TypeLoadException { @@ -1136,24 +954,6 @@ CC18: call void [System.Console]System.Console::WriteLine(object) ldc.i4.0 stloc.0 - leave.s CC19 - } -CC19: - ldstr "C19: override Base& M13() by Derived& M13()" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC19() - ldc.i4.0 - stloc.0 - leave.s CC20 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) leave.s CC20 } CC20: @@ -1181,7 +981,7 @@ CC21: .try { call void Main::RunTestC21() - leave.s CC22 + leave.s DONE } catch [mscorlib]System.TypeLoadException { @@ -1190,150 +990,6 @@ CC21: call void [System.Console]System.Console::WriteLine(object) ldc.i4.0 stloc.0 - leave.s CC22 - } -CC22: - ldstr "C22: override char& M14() by uint8& M14()" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC22() - ldc.i4.0 - stloc.0 - leave.s CC23 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC23 - } -CC23: - ldstr "C23: override bool* M15() by uint32* M15()" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC23() - ldc.i4.0 - stloc.0 - leave.s CC24 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC24 - } -CC24: - ldstr "C24: override bool* M15() by bool& M15()" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC24() - ldc.i4.0 - stloc.0 - leave.s CC25 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC25 - } -CC25: - ldstr "C25: override bool* M15() by int32 *(class Base) M15()" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC25() - ldc.i4.0 - stloc.0 - leave.s CC26 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC26 - } -CC26: - ldstr "C26: override char& M14() by char* M14()" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC26() - ldc.i4.0 - stloc.0 - leave.s CC27 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC27 - } -CC27: - ldstr "C27: override char& M14() by int32 *(class Base) M14()" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC27() - ldc.i4.0 - stloc.0 - leave.s CC28 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC28 - } -CC28: - ldstr "C28: override int32 *(class Base) M9() by int32* M9()" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC28() - ldc.i4.0 - stloc.0 - leave.s CC29 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s CC29 - } -CC29: - ldstr "C29: override int32 *(class Base) M9() by int32& M9()" - call void [System.Console]System.Console::WriteLine(string) - - .try - { - call void Main::RunTestC29() - ldc.i4.0 - stloc.0 - leave.s DONE - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) leave.s DONE } DONE: diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest_TypeLoadException.il b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest_TypeLoadException.il new file mode 100644 index 0000000000000..f513501d118f4 --- /dev/null +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest_TypeLoadException.il @@ -0,0 +1,1156 @@ +.assembly extern System.Console { } +.assembly extern xunit.core {} +.assembly extern System.Collections { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly 'CompatibleWithTest' { } + +.class public auto ansi abstract Base {} +.class public auto ansi abstract Derived extends Base {} + +.class public auto ansi beforefieldinit C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance int32[] M1() + { + ldnull + ret + } + + .method public hidebysig newslot virtual instance class [System.Runtime]System.Collections.Generic.IList`1 M2() + { + ldnull + ret + } + + .method public hidebysig newslot virtual instance int32 M3() + { + ldc.i4.0 + ret + } + + .method public hidebysig newslot virtual instance valuetype [mscorlib]System.Nullable`1 M4() + { + ldc.i4.0 + newobj instance void valuetype [mscorlib]System.Nullable`1::.ctor(!0) + ret + } + + .method public hidebysig newslot virtual instance class [System.Runtime]System.Collections.Generic.IList`1 M5() + { + ldnull + ret + } + + .method public hidebysig newslot virtual instance native int[] M6() + { + ldnull + ret + } + + .method public hidebysig newslot virtual instance class Base* M7() + { + ldc.i4.0 + conv.u + ret + } + + .method public hidebysig newslot virtual instance void* M8() + { + ldc.i4.0 + conv.u + ret + } + + .method public hidebysig newslot virtual instance method explicit instance int32 *(class Base) M9() + { + ldc.i4.0 + conv.u + ret + } + + .method public hidebysig newslot virtual instance int32* M10() + { + ldc.i4.0 + conv.u + ret + } + + .method public hidebysig newslot virtual instance native int* M11() + { + ldc.i4.0 + conv.u + ret + } + + .method public hidebysig newslot virtual instance uint32& M12() + { + ldc.i4.0 + conv.u + ret + } + + .method public hidebysig newslot virtual instance class Base& M13() + { + ldc.i4.0 + conv.u + ret + } + + .method public hidebysig newslot virtual instance char& M14() + { + ldc.i4.0 + conv.u + ret + } + + .method public hidebysig newslot virtual instance bool* M15() + { + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C2 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class [System.Runtime]System.Collections.Generic.IList`1 M1() + { + .override method instance int32[] C1::M1(); + ldnull + ret + } +} + +.class public auto ansi beforefieldinit D2 extends C2 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance int32 MD2() + { + ldc.i4.0 + ret + } +} + +.class public auto ansi beforefieldinit C3 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance int32[] M2() + { + .override method instance class [System.Runtime]System.Collections.Generic.IList`1 C1::M2(); + ldnull + ret + } +} + +.class public auto ansi beforefieldinit C4 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig virtual instance valuetype [mscorlib]System.Nullable`1 M3() + { + .override method instance int32 C1::M3(); + ldc.i4.0 + newobj instance void valuetype [mscorlib]System.Nullable`1::.ctor(!0) + ret + } +} + +.class public auto ansi beforefieldinit C5 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig virtual instance int32 M4() + { + .override method instance valuetype [mscorlib]System.Nullable`1 C1::M4(); + ldc.i4.0 + ret + } +} + +.class public auto ansi beforefieldinit C6 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig virtual instance uint32[] M1() + { + .override method instance int32[] C1::M1(); + ldnull + ret + } +} + +.class public auto ansi beforefieldinit C7 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance uint32[] M2() + { + .override method instance class [System.Runtime]System.Collections.Generic.IList`1 C1::M2(); + ldnull + ret + } +} + +.class public auto ansi beforefieldinit C8 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class Derived[] M5() + { + .override method instance class [System.Runtime]System.Collections.Generic.IList`1 C1::M5(); + ldnull + ret + } +} + +.class public auto ansi beforefieldinit C9 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig virtual instance uint64[] M6() + { + .override method instance native int[] C1::M6(); + ldnull + ret + } +} + +.class public auto ansi beforefieldinit C10 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig virtual instance uint32[] M6() + { + .override method instance native int[] C1::M6(); + ldnull + ret + } +} + +.class public auto ansi beforefieldinit C11 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class Derived* M7() + { + .override method instance class Base* C1::M7(); + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C12 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance int32* M8() + { + .override method instance void* C1::M8(); + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C13 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance method explicit instance int32 *(class Derived) M9() + { + .override method instance method explicit instance int32 *(class Base) C1::M9() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C14 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance method explicit instance int32 *(class C1) M9() + { + .override method instance method explicit instance int32 *(class Base) C1::M9() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C15 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance method explicit instance int32 *(class Base) M9() + { + .override method instance method explicit instance int32 *(class Base) C1::M9() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C16 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance uint32* M10() + { + .override method instance int32* C1::M10() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C17 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance native uint* M11() + { + .override method instance native int* C1::M11() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C18 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance int32& M12() + { + .override method instance uint32& C1::M12() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C19 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class Derived& M13() + { + .override method instance class Base& C1::M13() + + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C20 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance uint16& M14() + { + .override method instance char& C1::M14() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C21 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance uint8* M15() + { + .override method instance bool* C1::M15() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C22 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance uint8& M14() + { + .override method instance char& C1::M14() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C23 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance uint32* M15() + { + .override method instance bool* C1::M15() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C24 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance bool& M15() + { + .override method instance bool* C1::M15() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C25 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance method explicit instance int32 *(class Base) M15() + { + .override method instance bool* C1::M15() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C26 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance char* M14() + { + .override method instance char& C1::M14() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C27 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance method explicit instance int32 *(class Base) M14() + { + .override method instance char& C1::M14() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C28 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance int32* M9() + { + .override method instance method explicit instance int32 *(class Base) C1::M9() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit C29 extends C1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance int32& M9() + { + .override method instance method explicit instance int32 *(class Base) C1::M9() + ldc.i4.0 + conv.u + ret + } +} + +.class public auto ansi beforefieldinit Main extends [mscorlib]System.Object +{ + .method public static void RunTestC1() noinlining + { + newobj instance void class C1::.ctor() + callvirt instance int32[] class C1::M1() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC2() noinlining + { + newobj instance void class C2::.ctor() + callvirt instance int32[] class C1::M1() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestD2() noinlining + { + newobj instance void class D2::.ctor() + callvirt instance int32 class D2::MD2() + pop + ldstr "Unexpectedly succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC3() noinlining + { + newobj instance void class C3::.ctor() + callvirt instance class [System.Runtime]System.Collections.Generic.IList`1 class C1::M2() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC4() noinlining + { + newobj instance void class C4::.ctor() + callvirt instance int32 class C1::M3() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC5() noinlining + { + newobj instance void class C5::.ctor() + callvirt instance valuetype [mscorlib]System.Nullable`1 C1::M4() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC6() noinlining + { + newobj instance void class C6::.ctor() + callvirt instance int32[] class C1::M1() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC7() noinlining + { + newobj instance void class C7::.ctor() + callvirt instance class [System.Runtime]System.Collections.Generic.IList`1 class C1::M2() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC8() noinlining + { + newobj instance void class C8::.ctor() + callvirt instance class [System.Runtime]System.Collections.Generic.IList`1 class C1::M5() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC9() noinlining + { + newobj instance void class C9::.ctor() + callvirt instance native int[] class C1::M6() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC10() noinlining + { + newobj instance void class C10::.ctor() + callvirt instance native int[] class C1::M6() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC11() noinlining + { + newobj instance void class C11::.ctor() + callvirt instance class Base* class C1::M7() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC12() noinlining + { + newobj instance void class C12::.ctor() + callvirt instance void* class C1::M8() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC13() noinlining + { + newobj instance void class C13::.ctor() + callvirt instance method explicit instance int32 *(class Base) class C1::M9() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC14() noinlining + { + newobj instance void class C14::.ctor() + callvirt instance method explicit instance int32 *(class Base) class C1::M9() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC15() noinlining + { + newobj instance void class C15::.ctor() + callvirt instance method explicit instance int32 *(class Base) class C1::M9() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC16() noinlining + { + newobj instance void class C16::.ctor() + callvirt instance int32* class C1::M10() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC17() noinlining + { + newobj instance void class C17::.ctor() + callvirt instance native int* class C1::M11() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC18() noinlining + { + newobj instance void class C18::.ctor() + callvirt instance uint32& class C1::M12() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC19() noinlining + { + newobj instance void class C19::.ctor() + callvirt instance class Base& class C1::M13() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC20() noinlining + { + newobj instance void class C20::.ctor() + callvirt instance char& class C1::M14() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC21() noinlining + { + newobj instance void class C21::.ctor() + callvirt instance bool* class C1::M15() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC22() noinlining + { + newobj instance void class C22::.ctor() + callvirt instance char& class C1::M14() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC23() noinlining + { + newobj instance void class C23::.ctor() + callvirt instance bool* class C1::M15() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC24() noinlining + { + newobj instance void class C24::.ctor() + callvirt instance bool* class C1::M15() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC25() noinlining + { + newobj instance void class C25::.ctor() + callvirt instance bool* class C1::M15() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC26() noinlining + { + newobj instance void class C26::.ctor() + callvirt instance char& class C1::M14() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC27() noinlining + { + newobj instance void class C27::.ctor() + callvirt instance char& class C1::M14() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC28() noinlining + { + newobj instance void class C28::.ctor() + callvirt instance method explicit instance int32 *(class Base) class C1::M9() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC29() noinlining + { + newobj instance void class C29::.ctor() + callvirt instance method explicit instance int32 *(class Base) class C1::M9() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public hidebysig static int32 Main() cil managed + { + .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( + 01 00 00 00 + ) + .entrypoint + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + +CC2: + ldstr "C2: override int32[] by IList" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC2() + ldc.i4.0 + stloc.0 + leave.s CD2 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CD2 + } +CD2: + ldstr "D2: call non-overriding method MD2 when base class of D2 has invalid covariant override" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestD2() + ldc.i4.0 + stloc.0 + leave.s CC4 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC4 + } + +CC4: + ldstr "C4: override int32 by Nullable`1" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC4() + ldc.i4.0 + stloc.0 + leave.s CC5 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC5 + } +CC5: + ldstr "C5: override Nullable by int32" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC5() + ldc.i4.0 + stloc.0 + leave.s CC9 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC9 + } +CC9: + ldstr "C9: override native int[] by uint64[]" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC9() + ldc.i4.0 + stloc.0 + leave.s CC10 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC10 + } +CC10: + ldstr "C10: override native int[] by uint32[]" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC10() + ldc.i4.0 + stloc.0 + leave.s CC11 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC11 + } +CC11: + ldstr "C11: override Base* by Derived*" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC11() + ldc.i4.0 + stloc.0 + leave.s CC12 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC12 + } +CC12: + ldstr "C12: override void* by int32*" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC12() + ldc.i4.0 + stloc.0 + leave.s CC13 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC13 + } +CC13: + ldstr "C13: override int32 *(class Base) by int32 *(class Derived)" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC13() + ldc.i4.0 + stloc.0 + leave.s CC14 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC14 + } +CC14: + ldstr "C14: override int32 *(class Base) by int32 *(class C1)" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC14() + ldc.i4.0 + stloc.0 + leave.s CC19 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC19 + } +CC19: + ldstr "C19: override Base& M13() by Derived& M13()" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC19() + ldc.i4.0 + stloc.0 + leave.s CC22 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC22 + } +CC22: + ldstr "C22: override char& M14() by uint8& M14()" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC22() + ldc.i4.0 + stloc.0 + leave.s CC23 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC23 + } +CC23: + ldstr "C23: override bool* M15() by uint32* M15()" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC23() + ldc.i4.0 + stloc.0 + leave.s CC24 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC24 + } +CC24: + ldstr "C24: override bool* M15() by bool& M15()" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC24() + ldc.i4.0 + stloc.0 + leave.s CC25 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC25 + } +CC25: + ldstr "C25: override bool* M15() by int32 *(class Base) M15()" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC25() + ldc.i4.0 + stloc.0 + leave.s CC26 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC26 + } +CC26: + ldstr "C26: override char& M14() by char* M14()" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC26() + ldc.i4.0 + stloc.0 + leave.s CC27 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC27 + } +CC27: + ldstr "C27: override char& M14() by int32 *(class Base) M14()" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC27() + ldc.i4.0 + stloc.0 + leave.s CC28 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC28 + } +CC28: + ldstr "C28: override int32 *(class Base) M9() by int32* M9()" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC28() + ldc.i4.0 + stloc.0 + leave.s CC29 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s CC29 + } +CC29: + ldstr "C29: override int32 *(class Base) M9() by int32& M9()" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC29() + ldc.i4.0 + stloc.0 + leave.s DONE + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s DONE + } +DONE: + + ldloc.0 + brtrue.s PASS + + ldstr "Test FAILED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } +} diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest_TypeLoadException.ilproj b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest_TypeLoadException.ilproj new file mode 100644 index 0000000000000..b96c5451f7c56 --- /dev/null +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest_TypeLoadException.ilproj @@ -0,0 +1,11 @@ + + + + true + + true + + + + + diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il index 683c408220f80..21ff59a95e5f8 100644 --- a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il @@ -507,7 +507,7 @@ newobj instance void class GenDerivedTestType::.ctor() ldloca.s 1 - callvirt instance class GenDerive3 class GenTestType::MyGenFunc(string&) + callvirt instance class GenDerive3 class GenTestType::MyGenFunc(string&) pop newobj instance void class GenDerivedTestType::.ctor() @@ -535,7 +535,7 @@ newobj instance void class GenDerivedTestType::.ctor() ldloca.s 1 - callvirt instance class NonGenericDerived4 class GenTestType::MyGenFunc(string&) + callvirt instance class NonGenericDerived4 class GenTestType::MyGenFunc(string&) pop newobj instance void class GenDerivedTestType::.ctor() @@ -563,7 +563,7 @@ newobj instance void class GenDerivedTestType::.ctor() ldloca.s 1 - callvirt instance class GenToNonGen3 class GenTestType::GenToNonGen(string&) + callvirt instance class GenToNonGen3 class GenTestType::GenToNonGen(string&) pop newobj instance void class GenDerivedTestType::.ctor() @@ -591,7 +591,7 @@ newobj instance void class GenDerivedTestType::.ctor() ldloca.s 1 - callvirt instance class NonGenThroughGen4 class GenTestType::NonGenThroughGenFunc(string&) + callvirt instance class NonGenThroughGen4 class GenTestType::NonGenThroughGenFunc(string&) pop newobj instance void class GenDerivedTestType::.ctor() diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il index 4363a068307b1..8f2291b708d28 100644 --- a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il @@ -288,57 +288,6 @@ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } -// ======================================================================================== -// THIRD LAYER INVALID types: Couple of types that override some method from GenBaseType -// using a return type signature that would be incompatible with the return type used in -// GenMiddle. Loading these types will throw a TypeLoadException. -// ======================================================================================== - -.class public auto ansi beforefieldinit Invalid1 extends class GenMiddleType -{ - // Invalid: when comparing 'object' with !!Y in the instantiation of NonGenericDerived1 in the base type chain - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) - { - .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public auto ansi beforefieldinit Invalid2 extends class GenMiddleType -{ - // Invalid: when comparing 'object' with !!Y in the instantiation - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) - { - .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public auto ansi beforefieldinit Invalid3 extends class GenMiddleType -{ - // Invalid when comparing !!Y and 'object' in instantiation of GenRetType - .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) - { - .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public auto ansi beforefieldinit Invalid4 extends class GenMiddleType -{ - // Invalid when comparing !!Y and 'string' in instantiation of Dictionary - .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) - { - .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - // ======================================================================================== .class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object @@ -700,38 +649,6 @@ ret } - // ============== Test using GenMiddleType ============== // - // These test methods attempt to load the invalid types, and are - // expected to throw a TypeLoadException (caught by Main()) - - .method public static void RunInvalidTest1() noinlining - { - newobj instance void class Invalid1::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunInvalidTest2() noinlining - { - newobj instance void class Invalid2::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunInvalidTest3() noinlining - { - newobj instance void class Invalid3::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunInvalidTest4() noinlining - { - newobj instance void class Invalid4::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - // ===================================================================================== // .method public hidebysig static int32 Main() cil managed { @@ -801,82 +718,10 @@ M4: call bool CMain::RunTest_Middle4() - brtrue.s INVALID1 + brtrue.s DONE ldc.i4.0 stloc.0 - INVALID1: - .try - { - call void CMain::RunInvalidTest1() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid1." - call void [System.Console]System.Console::WriteLine(string) - leave.s INVALID2 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s INVALID2 - } - - INVALID2: - .try - { - call void CMain::RunInvalidTest2() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid2." - call void [System.Console]System.Console::WriteLine(string) - leave.s INVALID3 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s INVALID3 - } - - INVALID3: - .try - { - call void CMain::RunInvalidTest3() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid3." - call void [System.Console]System.Console::WriteLine(string) - leave.s INVALID4 - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s INVALID4 - } - - INVALID4: - .try - { - call void CMain::RunInvalidTest4() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid4." - call void [System.Console]System.Console::WriteLine(string) - leave.s DONE - } - catch [mscorlib]System.TypeLoadException - { - ldstr "Caught expected TypeLoadException:" - call void [System.Console]System.Console::WriteLine(string) - call void [System.Console]System.Console::WriteLine(object) - leave.s DONE - } - DONE: ldloc.0 brtrue.s PASS diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM_TypeLoadException.il b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM_TypeLoadException.il new file mode 100644 index 0000000000000..083ed85191e29 --- /dev/null +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM_TypeLoadException.il @@ -0,0 +1,583 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +.assembly extern System.Console { } +.assembly extern xunit.core {} +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly UnitTest_GVM_TypeLoadException { } + +// ======================================================================================== +// Types that will be used as return types on the various methods +// ======================================================================================== + +.class public auto ansi beforefieldinit A +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit B extends A +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit C extends B +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +.class public auto ansi beforefieldinit GenRetType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit Dictionary +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit NonGenericDerived5 extends class NonGenericDerived1 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +.class public auto ansi beforefieldinit GenToNonGen1 extends C +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends C +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit NonGenThroughGen5 extends class NonGenThroughGen2 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + + +// ======================================================================================== +// Main base type with various virtual methods that will be overridden later +// ======================================================================================== + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance object MyFunc(string& res) + { + ldarg.1 + ldstr "object GenBaseType.MyFunc()" + stind.ref + newobj instance void A::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B MyFunc(string& res) + { + ldarg.1 + ldstr "B GenBaseType.MyFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) + { + ldarg.1 + ldstr "B GenBaseType.GenToNonGen()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) + { + ldarg.1 + ldstr "B GenBaseType.NonGenThroughGenFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) + { + ldarg.1 + ldstr "GenRetType GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType> MyGenFunc(string& res) + { + ldarg.1 + ldstr "GenRetType> GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType>::.ctor() + ret + } +} + + +// ======================================================================================== +// SECOND LAYER type: overrides *SOME* virtuals on GenBaseType using MethodImpls with +// covariant return types (more derived return types) +// ======================================================================================== + +.class public auto ansi beforefieldinit GenMiddleType extends class GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) + ldarg.1 + ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGen(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) + ldarg.1 + ldstr "GenToNonGen1> GenMiddleType.GenToNonGen()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived1 MyGenFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) + ldarg.1 + ldstr "NonGenericDerived1 GenMiddleType.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive1> MyGenFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) + ldarg.1 + ldstr "GenDerive1> GenMiddleType.MyGenFunc()" + stind.ref + ldnull + ret + } +} + +// ======================================================================================== +// THIRD LAYER type: overrides all virtuals from GenBaseType using MethodImpls with +// covariant return types (more derived return types than the ones used in GenMiddleType) +// ======================================================================================== + +.class public auto ansi beforefieldinit GenTestType extends class GenMiddleType +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen5 NonGenThroughGenFunc(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) + ldarg.1 + ldstr "NonGenThroughGen5 TestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGen(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGen()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived5 MyGenFunc(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) + ldarg.1 + ldstr "NonGenericDerived5 TestType.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive2 MyGenFunc(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) + ldarg.1 + ldstr "GenDerive2 TestType.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenRetType MyFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance object class GenBaseType::MyFunc<[1]>(string& res) + ldarg.1 + ldstr "GenRetType TestType.MyFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C MyFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) + .override method instance class B class GenBaseType::MyFunc<[1]>(string& res) + ldarg.1 + ldstr "C TestType.MyFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +// ======================================================================================== +// THIRD LAYER INVALID types: Couple of types that override some method from GenBaseType +// using a return type signature that would be incompatible with the return type used in +// GenMiddle. Loading these types will throw a TypeLoadException. +// ======================================================================================== + +.class public auto ansi beforefieldinit Invalid1 extends class GenMiddleType +{ + // Invalid: when comparing 'object' with !!Y in the instantiation of NonGenericDerived1 in the base type chain + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) + ldnull + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit Invalid2 extends class GenMiddleType +{ + // Invalid: when comparing 'object' with !!Y in the instantiation + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) + ldnull + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit Invalid3 extends class GenMiddleType +{ + // Invalid when comparing !!Y and 'object' in instantiation of GenRetType + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) + ldnull + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi beforefieldinit Invalid4 extends class GenMiddleType +{ + // Invalid when comparing !!Y and 'string' in instantiation of Dictionary + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) + ldnull + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method private hidebysig static bool CheckResults ( + string expected, + string a, + [opt] string b, + [opt] string c, + [opt] string d) cil managed + { + .param [3] = nullref + .param [4] = nullref + .param [5] = nullref + // Method begins at RVA 0x20a0 + // Code size 164 (0xa4) + .maxstack 2 + .locals /* 11000002 */ init ( + [0] bool + ) + + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: call bool [System.Runtime]System.String::op_Equality(string, string) /* 0A000012 */ + IL_0007: stloc.0 + IL_0008: ldstr "EXPECTED: " /* 70000001 */ + IL_000d: ldarg.0 + IL_000e: call string [System.Runtime]System.String::Concat(string, string) /* 0A000013 */ + IL_0013: call void [System.Console]System.Console::WriteLine(string) /* 0A000014 */ + IL_0018: ldstr "ACTUAL1 : " /* 70000017 */ + IL_001d: ldarg.1 + IL_001e: call string [System.Runtime]System.String::Concat(string, string) /* 0A000013 */ + IL_0023: call void [System.Console]System.Console::WriteLine(string) /* 0A000014 */ + IL_0028: ldarg.2 + IL_0029: call bool [System.Runtime]System.String::IsNullOrEmpty(string) /* 0A000015 */ + IL_002e: brtrue.s IL_004e + + IL_0030: ldstr "ACTUAL2 : " /* 7000002D */ + IL_0035: ldarg.2 + IL_0036: call string [System.Runtime]System.String::Concat(string, string) /* 0A000013 */ + IL_003b: call void [System.Console]System.Console::WriteLine(string) /* 0A000014 */ + IL_0040: ldloc.0 + IL_0041: brfalse.s IL_004c + + IL_0043: ldarg.2 + IL_0044: ldarg.0 + IL_0045: call bool [System.Runtime]System.String::op_Equality(string, string) /* 0A000012 */ + IL_004a: br.s IL_004d + + IL_004c: ldc.i4.0 + + IL_004d: stloc.0 + + IL_004e: ldarg.3 + IL_004f: call bool [System.Runtime]System.String::IsNullOrEmpty(string) /* 0A000015 */ + IL_0054: brtrue.s IL_0074 + + IL_0056: ldstr "ACTUAL3 : " /* 70000043 */ + IL_005b: ldarg.3 + IL_005c: call string [System.Runtime]System.String::Concat(string, string) /* 0A000013 */ + IL_0061: call void [System.Console]System.Console::WriteLine(string) /* 0A000014 */ + IL_0066: ldloc.0 + IL_0067: brfalse.s IL_0072 + + IL_0069: ldarg.3 + IL_006a: ldarg.0 + IL_006b: call bool [System.Runtime]System.String::op_Equality(string, string) /* 0A000012 */ + IL_0070: br.s IL_0073 + + IL_0072: ldc.i4.0 + + IL_0073: stloc.0 + + IL_0074: ldarg.s d + IL_0076: call bool [System.Runtime]System.String::IsNullOrEmpty(string) /* 0A000015 */ + IL_007b: brtrue.s IL_009d + + IL_007d: ldstr "ACTUAL4 : " /* 70000059 */ + IL_0082: ldarg.s d + IL_0084: call string [System.Runtime]System.String::Concat(string, string) /* 0A000013 */ + IL_0089: call void [System.Console]System.Console::WriteLine(string) /* 0A000014 */ + IL_008e: ldloc.0 + IL_008f: brfalse.s IL_009b + + IL_0091: ldarg.s d + IL_0093: ldarg.0 + IL_0094: call bool [System.Runtime]System.String::op_Equality(string, string) /* 0A000012 */ + IL_0099: br.s IL_009c + + IL_009b: ldc.i4.0 + + IL_009c: stloc.0 + + IL_009d: call void [System.Console]System.Console::WriteLine() /* 0A000016 */ + IL_00a2: ldloc.0 + IL_00a3: ret + } // end of method Program::CheckResults + + // ============== Test using GenMiddleType ============== // + // These test methods attempt to load the invalid types, and are + // expected to throw a TypeLoadException (caught by Main()) + + .method public static void RunInvalidTest1() noinlining + { + newobj instance void class Invalid1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunInvalidTest2() noinlining + { + newobj instance void class Invalid2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunInvalidTest3() noinlining + { + newobj instance void class Invalid3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunInvalidTest4() noinlining + { + newobj instance void class Invalid4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + // ===================================================================================== // + .method public hidebysig static int32 Main() cil managed + { + .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( + 01 00 00 00 + ) + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + INVALID1: + .try + { + call void CMain::RunInvalidTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid1." + call void [System.Console]System.Console::WriteLine(string) + leave.s INVALID2 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s INVALID2 + } + + INVALID2: + .try + { + call void CMain::RunInvalidTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid2." + call void [System.Console]System.Console::WriteLine(string) + leave.s INVALID3 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s INVALID3 + } + + INVALID3: + .try + { + call void CMain::RunInvalidTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid3." + call void [System.Console]System.Console::WriteLine(string) + leave.s INVALID4 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s INVALID4 + } + + INVALID4: + .try + { + call void CMain::RunInvalidTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid4." + call void [System.Console]System.Console::WriteLine(string) + leave.s DONE + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught expected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + leave.s DONE + } + + DONE: + ldloc.0 + brtrue.s PASS + + ldstr "Test FAILED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + + ldc.i4.s 100 + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } +} diff --git a/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM_TypeLoadException.ilproj b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM_TypeLoadException.ilproj new file mode 100644 index 0000000000000..5dc084feab7af --- /dev/null +++ b/src/tests/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM_TypeLoadException.ilproj @@ -0,0 +1,9 @@ + + + + true + + + + + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 0440ee51964ac..ec449e4620b91 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1160,19 +1160,16 @@ - - + + - - - - - + + @@ -1304,6 +1301,9 @@ Doesn't pass after LLVM AOT compilation. + + Doesn't pass after LLVM AOT compilation. + Doesn't pass after LLVM AOT compilation.