From bf7501f15af679528045fe3b4efad549658543b3 Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Sun, 22 Mar 2020 19:41:49 -0700 Subject: [PATCH 01/21] Covariant Returns Feature: Allowing return types on MethodImpl to be derived types of the return type on the MethodDecl. Feature limitations: - Only supports MethodImpls and MethodDecls on classes (no interfaces/valuetypes). - MethodImpl and MethodDecl cannot be on the same type. - Interface/valuetypes not supported as covariant return types. Changes are mostly a boolean flag being passed around to allow for covariant type checking in method signatures. Generics are handled by correctly keeping track of the substitution chain while traversing the base type hierarchy for type comparison. All method signature comparisons uses metadata for checking, without loading any type (with some exceptions). Validation for the `ValidateMethodImplRemainsInEffectAttribute` is performed at the very last step of `CLASS_LOAD_EXACTPARENTS`. Inludes unit tests to cover positive/negative scenarios: - Non-generics - Generics, with various levels of complexities on generic instantiations and substitutions - GVMs - Delegates - Tests for validation of the existance/absence of the ValidateMethodImplRemainsInEffectAttribute - Interface and valuetype scenarios (negative scenarios) --- .../features/covariant-return-methods.md | 83 ++ src/coreclr/src/dlls/mscorrc/mscorrc.rc | 1 + src/coreclr/src/dlls/mscorrc/resource.h | 1 + src/coreclr/src/inc/sigbuilder.h | 2 + src/coreclr/src/utilcode/sigbuilder.cpp | 16 + src/coreclr/src/vm/class.cpp | 84 ++ src/coreclr/src/vm/classcompat.cpp | 5 +- src/coreclr/src/vm/clsload.hpp | 4 +- src/coreclr/src/vm/ecall.cpp | 2 +- src/coreclr/src/vm/memberload.cpp | 6 +- src/coreclr/src/vm/methodtablebuilder.cpp | 107 ++- src/coreclr/src/vm/methodtablebuilder.h | 7 +- src/coreclr/src/vm/runtimehandles.cpp | 3 +- src/coreclr/src/vm/siginfo.cpp | 538 ++++++++++++- src/coreclr/src/vm/siginfo.hpp | 77 +- src/coreclr/src/vm/wellknownattributes.h | 3 + .../InterfaceReturns/InterfaceReturns.il | 311 ++++++++ .../InterfaceReturns/InterfaceReturns.ilproj | 10 + .../InterfaceReturns/InterfaceReturns2.il | 271 +++++++ .../InterfaceReturns/InterfaceReturns2.ilproj | 10 + .../InterfaceReturns/InterfaceReturns3.il | 272 +++++++ .../InterfaceReturns/InterfaceReturns3.ilproj | 10 + .../InterfaceReturns/InterfaceReturns4.il | 272 +++++++ .../InterfaceReturns/InterfaceReturns4.ilproj | 10 + .../StructReturns/StructReturns.il | 276 +++++++ .../StructReturns/StructReturns.ilproj | 10 + .../StructReturns/StructReturns2.il | 276 +++++++ .../StructReturns/StructReturns2.ilproj | 10 + .../CovariantReturns/UnitTest/Modules/A.il | 9 + .../UnitTest/Modules/A.ilproj | 11 + .../CovariantReturns/UnitTest/Modules/B.il | 10 + .../UnitTest/Modules/B.ilproj | 11 + .../CovariantReturns/UnitTest/Modules/C.il | 10 + .../UnitTest/Modules/C.ilproj | 11 + .../UnitTest/Modules/Dictionary.il | 9 + .../UnitTest/Modules/Dictionary.ilproj | 11 + .../UnitTest/Modules/GenBaseType.il | 80 ++ .../UnitTest/Modules/GenBaseType.ilproj | 11 + .../UnitTest/Modules/GenDerive1.il | 10 + .../UnitTest/Modules/GenDerive1.ilproj | 11 + .../UnitTest/Modules/GenDerive2.il | 11 + .../UnitTest/Modules/GenDerive2.ilproj | 11 + .../UnitTest/Modules/GenDerive3.il | 11 + .../UnitTest/Modules/GenDerive3.ilproj | 11 + .../UnitTest/Modules/GenRetType.il | 9 + .../UnitTest/Modules/GenRetType.ilproj | 11 + .../UnitTest/Modules/GenTestType.il | 101 +++ .../UnitTest/Modules/GenTestType.ilproj | 11 + .../UnitTest/Modules/GenToNonGen1.il | 10 + .../UnitTest/Modules/GenToNonGen1.ilproj | 11 + .../UnitTest/Modules/GenToNonGen2.il | 11 + .../UnitTest/Modules/GenToNonGen2.ilproj | 11 + .../UnitTest/Modules/GenToNonGen3.il | 12 + .../UnitTest/Modules/GenToNonGen3.ilproj | 11 + .../UnitTest/Modules/NonGenThroughGen1.il | 9 + .../UnitTest/Modules/NonGenThroughGen1.ilproj | 11 + .../UnitTest/Modules/NonGenThroughGen2.il | 11 + .../UnitTest/Modules/NonGenThroughGen2.ilproj | 11 + .../UnitTest/Modules/NonGenThroughGen3.il | 10 + .../UnitTest/Modules/NonGenThroughGen3.ilproj | 11 + .../UnitTest/Modules/NonGenThroughGen4.il | 9 + .../UnitTest/Modules/NonGenThroughGen4.ilproj | 11 + .../UnitTest/Modules/NonGenericDerived1.il | 10 + .../Modules/NonGenericDerived1.ilproj | 11 + .../UnitTest/Modules/NonGenericDerived2.il | 10 + .../Modules/NonGenericDerived2.ilproj | 11 + .../UnitTest/Modules/NonGenericDerived3.il | 9 + .../Modules/NonGenericDerived3.ilproj | 11 + .../UnitTest/Modules/NonGenericDerived4.il | 9 + .../Modules/NonGenericDerived4.ilproj | 11 + .../UnitTest/OverrideMoreDerivedReturn.il | 469 ++++++++++++ .../UnitTest/OverrideMoreDerivedReturn.ilproj | 10 + .../UnitTest/OverrideSameReturn.il | 462 +++++++++++ .../UnitTest/OverrideSameReturn.ilproj | 10 + .../CovariantReturns/UnitTest/UnitTest.il | 570 ++++++++++++++ .../CovariantReturns/UnitTest/UnitTest.ilproj | 10 + .../UnitTest/UnitTestDelegates.il | 425 ++++++++++ .../UnitTest/UnitTestDelegates.ilproj | 10 + .../UnitTest/UnitTestMultiModule.il | 245 ++++++ .../UnitTest/UnitTestMultiModule.ilproj | 35 + .../CovariantReturns/UnitTest/UnitTest_GVM.il | 723 ++++++++++++++++++ .../UnitTest/UnitTest_GVM.ilproj | 10 + .../IncompatibleReturnNoValidation.il | 366 +++++++++ .../IncompatibleReturnNoValidation.ilproj | 10 + .../Validation/OverrideSameSigAsDecl.il | 483 ++++++++++++ .../Validation/OverrideSameSigAsDecl.ilproj | 10 + .../System.Private.CoreLib.Shared.projitems | 1 + ...idateMethodImplRemainsInEffectAttribute.cs | 11 + 88 files changed, 7085 insertions(+), 53 deletions(-) create mode 100644 docs/design/features/covariant-return-methods.md create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenTestType.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenTestType.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestMultiModule.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestMultiModule.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.ilproj create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs diff --git a/docs/design/features/covariant-return-methods.md b/docs/design/features/covariant-return-methods.md new file mode 100644 index 00000000000000..64c79b53afb2db --- /dev/null +++ b/docs/design/features/covariant-return-methods.md @@ -0,0 +1,83 @@ +# Covariant Return Methods + +Covariant return methods is a runtime feature designed to support the [covariant return types](https://github.com/dotnet/csharplang/blob/master/proposals/covariant-returns.md) and [records](https://github.com/dotnet/csharplang/blob/master/proposals/records.md) C# language features posed for C# 9.0. + +This feature allows an overriding method to have a more derived reference type than the method it overrides. Covariant return methods can only be described through MethodImpl records, and as an initial implementation, will have the following limitations: +1. Covariant return methods will only be applicable to methods on reference types: the MethodDecl and MethodImpl records can only be on reference types. Methods on interfaces will not be supported. +2. Return types in covariant return methods can only be reference types: covariant interface return types are not supported. + +Supporting interfaces comes with many complications (ex: interface equivalence, default interface methods, variance on generic interfaces, etc...), which is why the feature will initially only support classes. + +MethodImpl checking will allow a return type to vary as long as the override is compatible with the return type of the method overriden (i.e. a derived type). + +If a language wishes for the override to be semantically visible such that users of the more derived type may rely on the covariant return type it shall make the override a newslot method with appropriate visibility AND name to be used outside of the class. + +For virtual method slot MethodImpl overrides, each slot shall be checked for compatible signature on type load. (Implementation note: This behavior can be triggered only if the type has a covariant return type override in its hierarchy, so as to make this pay for play.) + +A new `ValidateMethodImplRemainsInEffectAttribute` shall be added. The presence of this attribute is to require the type loader to ensure that the MethodImpl records specified on the method have not lost their slot unifying behavior due to other actions. In other words, when a MethodImpl on type A overrides some method using a derived return type in the signature, any type deriving from A will be allowed to have a MethodImpl record that overrides the same method as long as the return type used in the signature is the same or more derived than the return type used in the MethodImpl signature on type A. This is used to allow the C# language to require that overrides have the consistent behaviors expected. The expectation is that C# would place this attribute on covariant override methods in classes. + +## Implementation Notes + +### Signature Checking + +Signature checking for MethodImpl is done through the `MetaSig::CompareElementType` method, which is called from various places in the runtime when comparing method signatures. This method compares the signatures of two types, and will now take a boolean flag that would allow for derived type checking behavior. The boolean flag will be set to `TRUE` appropriately during comparison of the return type signatures between a MethodImpl and MethodDecl records. + +The type signature checking algorithm will perform the following: +1. Traverse and compare the signatures for `type1` and `type2` recursively. +2. If the signatures mismatch at any given point, and the current element type for `type2` is `ELEMENT_TYPE_CLASS` or `ELEMENT_TYPE_GENERICINST`: + + Check if base type comparison is allowed + + Compute the parent type's signature and parent type's generic substitution of `type2` + + Perform a recursive call to re-compare `type1` with the new parent type signature of `type2`. + +Note: if `ELEMENT_TYPE_INTERNAL` is encountered in either of the type signatures, both types will be fully loaded and compared for compatibility. + +### VTable Slot Validation + +Validation will only be performed if the `ValidateMethodImplRemainsInEffectAttribute` exists on the type that needs validation. Validation is only performed on the type where the attribute is added, and does not propagate to its base or derived types (every type that needs to be validated needs to have this attribute). + +Validation is performed at the very last step of `CLASS_LOAD_EXACTPARENTS`, after all base types have been loaded, and the vtable has been fully built. + +The validation algorithm will perform the following: +1. For each slot in the vtable that also exists in the vtable of the base type: + + Check if the `MethodDesc` on that slot has a different original slot value. If not, continue. + + Let `hType1` be the `TypeHandle` of the return type of the method on base type. + + Let `hType2` be the `TypeHandle` of the return type of the method on the current type being validated. + + Verify that `hType2` is the same type as, or a derived type of `hType1` + +### [Future] Interface Support + +An interface method may be both non-final and have a MethodImpl that declares that it overrides another interface method. If it does, NO other interface method may .override it. Instead further overrides must override the method that it overrode. Also the overriding method may only override 1 method. + +The default interface method resolution algorithm shall change from: + +``` console +Given interface method M and type T. +Let MSearch = M +Let MFound = Most specific implementation within the interfaces for MSearch within type T. If multiple implementations are found, throw Ambiguous match exception. +Return MFound +``` + +To: + +``` console +Given interface method M and type T. +Let MSearch = M + +If (MSearch overrides another method MBase) + Let MSearch = MBase + +Let MFound = Most specific implementation within the interfaces for MSearch within type T. If multiple implementations are found, throw Ambiguous match exception. +Let M Code = NULL + +If ((MFound != Msearch) and (MFound is not final)) + Let M ClassVirtual = ResolveInterfaceMethod for MFound to virtual override on class T without using Default interface method implementation or return NULL if not found. + If (M ClassVirtual != NULL) + Let M Code= ResolveVirtualMethod for MFound on class T to implementation method + +If (M Code != NULL) + Let M Code = MFound + +Check M Code For signature interface method M. + +Return M Code +``` diff --git a/src/coreclr/src/dlls/mscorrc/mscorrc.rc b/src/coreclr/src/dlls/mscorrc/mscorrc.rc index 8a7410ef25b2d5..9337b473d7aac6 100644 --- a/src/coreclr/src/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/src/dlls/mscorrc/mscorrc.rc @@ -421,6 +421,7 @@ BEGIN IDS_CLASSLOAD_MI_BODY_DECL_MISMATCH "Signature of the body and declaration in a method implementation do not match. Type: '%1'. Assembly: '%2'." IDS_CLASSLOAD_MI_MISSING_SIG_BODY "Signature for the body in a method implementation cannot be found. Type: '%1'. Assembly: '%2'." IDS_CLASSLOAD_MI_MISSING_SIG_DECL "Signature for the declaration in a method implementation cannot be found. Type: '%1'. Assembly: '%2'." + IDS_CLASSLOAD_MI_BADRETURNTYPE "Return type in method '%1' on type '%2' from assembly '%3' is not compatible with base type method '%4'." IDS_CLASSLOAD_EQUIVALENTSTRUCTMETHODS "Could not load the structure '%1' from assembly '%2'. The structure is marked as eligible for type equivalence, but it has a method." IDS_CLASSLOAD_EQUIVALENTSTRUCTFIELDS "Could not load the structure '%1' from assembly '%2'. The structure is marked as eligible for type equivalence, but it has a static or non-public field." diff --git a/src/coreclr/src/dlls/mscorrc/resource.h b/src/coreclr/src/dlls/mscorrc/resource.h index 342c0570d493bb..a75aa00afe1d3a 100644 --- a/src/coreclr/src/dlls/mscorrc/resource.h +++ b/src/coreclr/src/dlls/mscorrc/resource.h @@ -167,6 +167,7 @@ #define IDS_CLASSLOAD_MI_BODY_DECL_MISMATCH 0x17a5 #define IDS_CLASSLOAD_MI_MISSING_SIG_BODY 0x17a6 #define IDS_CLASSLOAD_MI_MISSING_SIG_DECL 0x17a7 +#define IDS_CLASSLOAD_MI_BADRETURNTYPE 0x17a8 #define IDS_CLASSLOAD_TOOMANYGENERICARGS 0x17ab #define IDS_ERROR 0x17b0 diff --git a/src/coreclr/src/inc/sigbuilder.h b/src/coreclr/src/inc/sigbuilder.h index c1ad67af0f2e34..938e50d8f31346 100644 --- a/src/coreclr/src/inc/sigbuilder.h +++ b/src/coreclr/src/inc/sigbuilder.h @@ -74,6 +74,8 @@ class SigBuilder } void AppendBlob(const PVOID pBlob, SIZE_T cbBlob); + + void AppendSignature(const PCCOR_SIGNATURE pSig, const PCCOR_SIGNATURE pSigEnd); }; #endif // _SIGBUILDER_H_ diff --git a/src/coreclr/src/utilcode/sigbuilder.cpp b/src/coreclr/src/utilcode/sigbuilder.cpp index 922e1613ca3697..58d0c374cf66a0 100644 --- a/src/coreclr/src/utilcode/sigbuilder.cpp +++ b/src/coreclr/src/utilcode/sigbuilder.cpp @@ -119,6 +119,22 @@ void SigBuilder::AppendBlob(const PVOID pBlob, SIZE_T cbBlob) m_dwLength += (DWORD)cbBlob; } +void SigBuilder::AppendSignature(const PCCOR_SIGNATURE pSig, const PCCOR_SIGNATURE pSigEnd) +{ + STANDARD_VM_CONTRACT; + + // Overflow checks + if (pSigEnd < pSig) + ThrowOutOfMemory(); + + DWORD cbSig = (DWORD)(pSigEnd - pSig); + + Ensure(cbSig); + memcpy(&m_pBuffer[m_dwLength], pSig, cbSig); + + m_dwLength += cbSig; +} + void SigBuilder::Grow(SIZE_T cbMin) { STANDARD_VM_CONTRACT; diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index c87c21d1515952..1a71a594047d8a 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -967,12 +967,96 @@ void ClassLoader::LoadExactParents(MethodTable *pMT) MethodTableBuilder::CopyExactParentSlots(pMT, pApproxParentMT); + ValidateMethodImplRemainsInEffect(pMT); + // We can now mark this type as having exact parents pMT->SetHasExactParent(); RETURN; } +/*static*/ +void ClassLoader::ValidateMethodImplRemainsInEffect(MethodTable* pMT) +{ + CONTRACT_VOID + { + STANDARD_VM_CHECK; + PRECONDITION(CheckPointer(pMT)); + } + CONTRACT_END; + + // Validation not applicable to interface types and value types, since these are not currently + // supported with the covariant return feature + if (pMT->IsInterface() || pMT->IsValueType()) + RETURN; + + MethodTable* pParentMT = pMT->GetParentMethodTable(); + if (pParentMT == NULL) + RETURN; + + // If the ValidateMethodImplRemainsInEffect attribute does not exist on the type, it will not be validated. + BYTE* pVal = NULL; + ULONG cbVal = 0; + HRESULT hr = pMT->GetCustomAttribute(WellKnownAttribute::ValidateMethodImplRemainsInEffectAttribute, (const void**)&pVal, &cbVal); + if (hr != S_OK) + RETURN; + + for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++) + { + MethodDesc* pMD = pMT->GetMethodDescForSlot(i); + MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i); + + DWORD originalIndex = pMD->GetSlot(); + if (originalIndex == i) + continue; + + DWORD originalIndexParent = pParentMD->GetSlot(); + if (originalIndex == originalIndexParent) + continue; + + // If we reach this point, it means we have a MethodImpl override. With the covariant return feature, the presense of the + // ValidateMethodImplRemainsInEffect attribute is used to validate that if a method gets overridden, the return type + // in the new override is the same type or a more derived type as the return type of the method being overriden. + + // The context used to load the return type of the parent method has to use the generic method arguments + // of the overriding method, otherwise the type comparison below will not work correctly + SigTypeContext context1(pParentMD->GetClassInstantiation(), pMD->GetMethodInstantiation()); + MetaSig methodSig1(pParentMD); + TypeHandle hType1 = methodSig1.GetReturnProps().GetTypeHandleThrowing(pParentMD->GetModule(), &context1, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS); + + SigTypeContext context2(pMD); + MetaSig methodSig2(pMD); + TypeHandle hType2 = methodSig2.GetReturnProps().GetTypeHandleThrowing(pMD->GetModule(), &context2, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS); + + // Type1 has to be equal to Type2, or a base type of Type2 (covariant returns) + + if (!MetaSig::CompareTypeHandles(hType1, hType2, TRUE /* allowDerivedClass */ )) + { + SString strAssemblyName; + pMD->GetAssembly()->GetDisplayName(strAssemblyName); + + SString strInvalidTypeName; + TypeString::AppendType(strInvalidTypeName, TypeHandle(pMD->GetMethodTable())); + + SString strInvalidMethodName; + TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation()); + + SString strParentMethodName; + TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation()); + + COMPlusThrow( + kTypeLoadException, + IDS_CLASSLOAD_MI_BADRETURNTYPE, + strInvalidMethodName, + strInvalidTypeName, + strAssemblyName, + strParentMethodName); + } + } + + RETURN; +} + //******************************************************************************* // This is the routine that computes the internal type of a given type. It normalizes // structs that have only one field (of int/ptr sized values), to be that underlying type. diff --git a/src/coreclr/src/vm/classcompat.cpp b/src/coreclr/src/vm/classcompat.cpp index f74c2247ba29d6..c89c4ee6067fb6 100644 --- a/src/coreclr/src/vm/classcompat.cpp +++ b/src/coreclr/src/vm/classcompat.cpp @@ -1405,7 +1405,7 @@ VOID MethodTableBuilder::BuildInteropVTable_PlaceVtableMethods( bmtType->pModule, NULL, pInterfaceMethodSig, cInterfaceMethodSig, - pInterfaceMD->GetModule(), NULL)) + pInterfaceMD->GetModule(), NULL, FALSE)) { // Found match, break from loop break; } @@ -2263,7 +2263,8 @@ VOID MethodTableBuilder::EnumerateMethodImpls() pSigBody, cbSigBody, bmtType->pModule, - NULL)) + NULL, + FALSE)) { BuildMethodTableThrowException(IDS_CLASSLOAD_MI_BODY_DECL_MISMATCH); } diff --git a/src/coreclr/src/vm/clsload.hpp b/src/coreclr/src/vm/clsload.hpp index 23a051f6aeef45..fb569e93c7c130 100644 --- a/src/coreclr/src/vm/clsload.hpp +++ b/src/coreclr/src/vm/clsload.hpp @@ -969,10 +969,12 @@ class ClassLoader // Phase CLASS_LOAD_EXACTPARENTS of class loading // Load exact parents and interfaces and dependent structures (generics dictionary, vtable fixes) - static void LoadExactParents(MethodTable *pMT); + static void LoadExactParents(MethodTable* pMT); static void LoadExactParentAndInterfacesTransitively(MethodTable *pMT); + static void ValidateMethodImplRemainsInEffect(MethodTable* pMT); + // Create a non-canonical instantiation of a generic type based off the canonical instantiation // (For example, MethodTable for List is based on the MethodTable for List<__Canon>) static TypeHandle CreateTypeHandleForNonCanonicalGenericInstantiation(TypeKey *pTypeKey, diff --git a/src/coreclr/src/vm/ecall.cpp b/src/coreclr/src/vm/ecall.cpp index 7231cd3ff8f15a..414838c01fa108 100644 --- a/src/coreclr/src/vm/ecall.cpp +++ b/src/coreclr/src/vm/ecall.cpp @@ -349,7 +349,7 @@ static INT FindECIndexForMethod(MethodDesc *pMD, const LPVOID* impls) //@GENERICS: none of these methods belong to generic classes so there is no instantiation info to pass in if (!MetaSig::CompareMethodSigs(pMethodSig, cbMethodSigLen, pModule, NULL, - sig.GetRawSig(), sig.GetRawSigLen(), MscorlibBinder::GetModule(), NULL)) + sig.GetRawSig(), sig.GetRawSigLen(), MscorlibBinder::GetModule(), NULL, FALSE)) { continue; } diff --git a/src/coreclr/src/vm/memberload.cpp b/src/coreclr/src/vm/memberload.cpp index 1881b3f0b779ce..c0e26d74d32f5e 100644 --- a/src/coreclr/src/vm/memberload.cpp +++ b/src/coreclr/src/vm/memberload.cpp @@ -243,7 +243,7 @@ void MemberLoader::GetDescFromMemberRef(Module * pModule, pMethodDef->GetSig(&pMethodSig, &cMethodSig); if (!MetaSig::CompareMethodSigs(pSig, cSig, pModule, NULL, pMethodSig, - cMethodSig, pModule, NULL)) + cMethodSig, pModule, NULL, FALSE)) { // If the signatures do not match, then the correct MethodDesc has not been found. fMissingMethod = TRUE; @@ -1043,7 +1043,7 @@ BOOL CompareMethodSigWithCorrectSubstitution( pCurDeclMD->GetSig(&pCurMethodSig, &cCurMethodSig); return MetaSig::CompareMethodSigs(pSignature, cSignature, pModule, NULL, pCurMethodSig, - cCurMethodSig, pCurDeclMD->GetModule(), pDefSubst); + cCurMethodSig, pCurDeclMD->GetModule(), pDefSubst, FALSE); } else { @@ -1443,7 +1443,7 @@ MemberLoader::FindConstructor(MethodTable * pMT, PCCOR_SIGNATURE pSignature,DWOR DWORD cCurMethodSig; pCurMethod->GetSig(&pCurMethodSig, &cCurMethodSig); - if (MetaSig::CompareMethodSigs(pSignature, cSignature, pModule, NULL, pCurMethodSig, cCurMethodSig, pCurMethod->GetModule(), NULL)) + if (MetaSig::CompareMethodSigs(pSignature, cSignature, pModule, NULL, pCurMethodSig, cCurMethodSig, pCurMethod->GetModule(), NULL, FALSE)) { return pCurMethod; } diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 14ccfd4371061d..e124da2ee66dd4 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -892,13 +892,15 @@ MethodTableBuilder::MethodSignature::NamesEqual( /*static*/ bool MethodTableBuilder::MethodSignature::SignaturesEquivalent( const MethodSignature & sig1, - const MethodSignature & sig2) + const MethodSignature & sig2, + BOOL allowCovariantReturn) { STANDARD_VM_CONTRACT; return !!MetaSig::CompareMethodSigs( sig1.GetSignature(), static_cast(sig1.GetSignatureLength()), sig1.GetModule(), &sig1.GetSubstitution(), - sig2.GetSignature(), static_cast(sig2.GetSignatureLength()), sig2.GetModule(), &sig2.GetSubstitution()); + sig2.GetSignature(), static_cast(sig2.GetSignatureLength()), sig2.GetModule(), &sig2.GetSubstitution(), + allowCovariantReturn); } //******************************************************************************* @@ -913,7 +915,7 @@ MethodTableBuilder::MethodSignature::SignaturesExactlyEqual( return !!MetaSig::CompareMethodSigs( sig1.GetSignature(), static_cast(sig1.GetSignatureLength()), sig1.GetModule(), &sig1.GetSubstitution(), sig2.GetSignature(), static_cast(sig2.GetSignatureLength()), sig2.GetModule(), &sig2.GetSubstitution(), - &newVisited); + FALSE, &newVisited); } //******************************************************************************* @@ -923,7 +925,7 @@ MethodTableBuilder::MethodSignature::Equivalent( { STANDARD_VM_CONTRACT; - return NamesEqual(*this, rhs) && SignaturesEquivalent(*this, rhs); + return NamesEqual(*this, rhs) && SignaturesEquivalent(*this, rhs, FALSE); } //******************************************************************************* @@ -2156,6 +2158,83 @@ BOOL MethodTableBuilder::bmtMetaDataInfo::MethodImplTokenPair::Equal( (elem1->methodDecl == elem2->methodDecl)); } +//******************************************************************************* +BOOL MethodTableBuilder::IsEligibleForCovariantReturns(mdToken methodDeclToken) +{ + STANDARD_VM_CONTRACT; + + // + // Note on covariant return types: right now we only support covariant returns for MethodImpls on + // classes, where the MethodDecl is also on a class. Interface methods are not supported. + // We will also allow covariant return types if both the MethodImpl and MethodDecl are not on the same type. + // + + HRESULT hr = S_OK; + IMDInternalImport* pMDInternalImport = GetMDImport(); + + // First, check if the type with the MethodImpl is a class. + if (IsValueClass() || IsInterface()) + return FALSE; + + mdToken tkParent; + hr = pMDInternalImport->GetParentToken(methodDeclToken, &tkParent); + if (FAILED(hr)) + BuildMethodTableThrowException(hr, *bmtError); + + // Second, check that the type with the MethodImpl is not the same as the type with the MethodDecl + if (GetCl() == tkParent) + return FALSE; + + // Finally, check that the type with the MethodDecl is not an interface. To do so, we need to compute the TypeDef + // token of the type with the MethodDecl, as well as its module, in order to use the metadata to check if the type + // is an interface. + mdToken declTypeDefToken = mdTokenNil; + Module* pDeclModule = GetModule(); + if (TypeFromToken(tkParent) == mdtTypeRef || TypeFromToken(tkParent) == mdtTypeDef) + { + if (!ClassLoader::ResolveTokenToTypeDefThrowing(GetModule(), tkParent, &pDeclModule, &declTypeDefToken)) + return FALSE; + } + else if (TypeFromToken(tkParent) == mdtTypeSpec) + { + ULONG cbTypeSig; + PCCOR_SIGNATURE pTypeSig; + hr = pMDInternalImport->GetSigFromToken(tkParent, &cbTypeSig, &pTypeSig); + if (FAILED(hr)) + BuildMethodTableThrowException(hr, *bmtError); + + SigParser parser(pTypeSig, cbTypeSig); + + CorElementType elementType; + IfFailThrow(parser.GetElemType(&elementType)); + + if (elementType == ELEMENT_TYPE_GENERICINST) + { + IfFailThrow(parser.GetElemType(&elementType)); + } + + if (elementType == ELEMENT_TYPE_CLASS) + { + mdToken declTypeDefOrRefToken; + IfFailThrow(parser.GetToken(&declTypeDefOrRefToken)); + if (!ClassLoader::ResolveTokenToTypeDefThrowing(GetModule(), declTypeDefOrRefToken, &pDeclModule, &declTypeDefToken)) + return FALSE; + } + } + + if (declTypeDefToken == mdTokenNil) + return FALSE; + + // Now that we have computed the TypeDef token and the module, check its attributes to verify it is not an interface. + + DWORD attr; + hr = pDeclModule->GetMDImport()->GetTypeDefProps(declTypeDefToken, &attr, NULL); + if (FAILED(hr)) + BuildMethodTableThrowException(hr, *bmtError); + + return !IsTdInterface(attr); +} + //******************************************************************************* VOID MethodTableBuilder::EnumerateMethodImpls() @@ -2365,6 +2444,9 @@ MethodTableBuilder::EnumerateMethodImpls() { BuildMethodTableThrowException(IDS_CLASSLOAD_MI_MISSING_SIG_BODY); } + + BOOL allowCovariantReturn = IsEligibleForCovariantReturns(theDecl); + // Can't use memcmp because there may be two AssemblyRefs // in this scope, pointing to the same assembly, etc.). if (!MetaSig::CompareMethodSigs( @@ -2375,7 +2457,8 @@ MethodTableBuilder::EnumerateMethodImpls() pSigBody, cbSigBody, GetModule(), - NULL)) + NULL, + allowCovariantReturn)) { BuildMethodTableThrowException(IDS_CLASSLOAD_MI_BODY_DECL_MISMATCH); } @@ -3648,10 +3731,10 @@ BOOL MethodTableBuilder::IsSelfReferencingStaticValueTypeField(mdToken dwByV PCCOR_SIGNATURE pFieldSig = pMemberSignature + 1; // skip the CALLCONV_FIELD - return MetaSig::CompareElementType(pFakeSig, pFieldSig, + return MetaSig::CompareElementType(pFakeSig, pFieldSig, pFakeSig + cFakeSig, pMemberSignature + cMemberSignature, GetModule(), GetModule(), - NULL, NULL); + NULL, NULL, FALSE); } @@ -5818,6 +5901,7 @@ MethodTableBuilder::ProcessMethodImpls() cbCurMDSig, pCurMD->GetModule(), &pCurDeclType->GetSubstitution(), + FALSE, iPass == 0 ? &newVisited : NULL)) { declMethod = (*bmtParent->pSlotTable)[pCurMD->GetSlot()].Decl(); @@ -6118,6 +6202,7 @@ VOID MethodTableBuilder::MethodImplCompareSignatures( bmtMethodHandle hDecl, bmtMethodHandle hImpl, + BOOL allowCovariantReturn, DWORD dwConstraintErrorCode) { CONTRACTL { @@ -6131,7 +6216,7 @@ MethodTableBuilder::MethodImplCompareSignatures( const MethodSignature &declSig(hDecl.GetMethodSignature()); const MethodSignature &implSig(hImpl.GetMethodSignature()); - if (!MethodSignature::SignaturesEquivalent(declSig, implSig)) + if (!MethodSignature::SignaturesEquivalent(declSig, implSig, allowCovariantReturn)) { LOG((LF_CLASSLOADER, LL_INFO1000, "BADSIG placing MethodImpl: %x\n", declSig.GetToken())); BuildMethodTableThrowException(COR_E_TYPELOAD, IDS_CLASSLOAD_MI_BADSIGNATURE, declSig.GetToken()); @@ -6379,6 +6464,7 @@ MethodTableBuilder::PlaceLocalDeclarationOnClass( MethodImplCompareSignatures( pDecl, pImpl, + FALSE /* allowCovariantReturn */, IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_LOCAL_METHOD_IMPL); /////////////////////////////// @@ -6450,6 +6536,7 @@ VOID MethodTableBuilder::PlaceInterfaceDeclarationOnClass( MethodImplCompareSignatures( pDecl, pImpl, + FALSE /* allowCovariantReturn */, IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_INTERFACE_METHOD_IMPL); /////////////////////////////// @@ -6552,6 +6639,7 @@ VOID MethodTableBuilder::PlaceInterfaceDeclarationOnInterface( MethodImplCompareSignatures( hDecl, bmtMethodHandle(pImpl), + FALSE /* allowCovariantReturn */, IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_INTERFACE_METHOD_IMPL); /////////////////////////////// @@ -6600,6 +6688,7 @@ MethodTableBuilder::PlaceParentDeclarationOnClass( MethodImplCompareSignatures( pDecl, pImpl, + TRUE /* allowCovariantReturn */, IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_PARENT_METHOD_IMPL); //////////////////////////////// @@ -7230,7 +7319,7 @@ MethodTableBuilder::PlaceMethodFromParentEquivalentInterfaceIntoInterfaceSlot( // Check to verify that the equivalent slot on the equivalent interface actually matches the method // on the current interface. If not, then the slot is not a match, and we should search other interfaces // for an implementation of the method. - if (!MethodSignature::SignaturesEquivalent(pCurItfMethod->GetMethodSignature(), parentImplementation.GetMethodSignature())) + if (!MethodSignature::SignaturesEquivalent(pCurItfMethod->GetMethodSignature(), parentImplementation.GetMethodSignature(), FALSE)) { continue; } diff --git a/src/coreclr/src/vm/methodtablebuilder.h b/src/coreclr/src/vm/methodtablebuilder.h index 7314c704a1142c..dda4ae978ad583 100644 --- a/src/coreclr/src/vm/methodtablebuilder.h +++ b/src/coreclr/src/vm/methodtablebuilder.h @@ -809,7 +809,8 @@ class MethodTableBuilder static bool SignaturesEquivalent( const MethodSignature & sig1, - const MethodSignature & sig2); + const MethodSignature & sig2, + BOOL allowCovariantReturn); //----------------------------------------------------------------------------------------- // Returns true if the metadata signatures (PCCOR_SIGNATURE) are exactly equal. (No type equivalence permitted) @@ -2562,6 +2563,9 @@ class MethodTableBuilder mdToken* pDeclaration, // Method definition for Member BOOL fSameClass); // Does the declaration need to be in this class + BOOL + IsEligibleForCovariantReturns(mdToken methodDeclToken); + // -------------------------------------------------------------------------------------------- // Enumerates the method impl token pairs and resolves the impl tokens to mdtMethodDef // tokens, since we currently have the limitation that all impls are in the current class. @@ -2739,6 +2743,7 @@ class MethodTableBuilder MethodImplCompareSignatures( bmtMethodHandle hDecl, bmtMethodHandle hImpl, + BOOL allowCovariantReturn, DWORD dwConstraintErrorCode); // -------------------------------------------------------------------------------------------- diff --git a/src/coreclr/src/vm/runtimehandles.cpp b/src/coreclr/src/vm/runtimehandles.cpp index 2b4cad229bb447..a4846515f92c88 100644 --- a/src/coreclr/src/vm/runtimehandles.cpp +++ b/src/coreclr/src/vm/runtimehandles.cpp @@ -2169,7 +2169,8 @@ FCIMPL2(FC_BOOL_RET, SignatureNative::CompareSig, SignatureNative* pLhsUNSAFE, S { ret = MetaSig::CompareMethodSigs( gc.pLhs->GetCorSig(), gc.pLhs->GetCorSigSize(), gc.pLhs->GetModule(), NULL, - gc.pRhs->GetCorSig(), gc.pRhs->GetCorSigSize(), gc.pRhs->GetModule(), NULL); + gc.pRhs->GetCorSig(), gc.pRhs->GetCorSigSize(), gc.pRhs->GetModule(), NULL, + FALSE); } HELPER_METHOD_FRAME_END(); FC_RETURN_BOOL(ret); diff --git a/src/coreclr/src/vm/siginfo.cpp b/src/coreclr/src/vm/siginfo.cpp index dc21a23eac1eb5..ee16c3cb678768 100644 --- a/src/coreclr/src/vm/siginfo.cpp +++ b/src/coreclr/src/vm/siginfo.cpp @@ -713,7 +713,7 @@ static BOOL MethodDescMatchesSig(MethodDesc* pMD, PCCOR_SIGNATURE pSig, DWORD cS pMD->GetSig(&pSigOfMD, &cSigOfMD); return MetaSig::CompareMethodSigs(pSig, cSig, pModule, NULL, - pSigOfMD, cSigOfMD, pMD->GetModule(), NULL); + pSigOfMD, cSigOfMD, pMD->GetModule(), NULL, FALSE); } #endif // _DEBUG @@ -3007,7 +3007,7 @@ static BOOL CompareDelegatesForEquivalence(mdToken tk1, mdToken tk2, Module *pMo GetDelegateInvokeMethodSignature(tk1, pModule1, &cbSig1, &pSig1); GetDelegateInvokeMethodSignature(tk2, pModule2, &cbSig2, &pSig2); - return MetaSig::CompareMethodSigs(pSig1, cbSig1, pModule1, NULL, pSig2, cbSig2, pModule2, NULL, pVisited); + return MetaSig::CompareMethodSigs(pSig1, cbSig1, pModule1, NULL, pSig2, cbSig2, pModule2, NULL, FALSE, pVisited); } #endif // FEATURE_TYPEEQUIVALENCE @@ -3567,6 +3567,346 @@ BOOL CompareTypeTokens(mdToken tk1, mdToken tk2, Module *pModule1, Module *pModu #pragma warning(push) #pragma warning(disable:21000) // Suppress PREFast warning about overly large function #endif + +//--------------------------------------------------------------------------------------- +// +// Compare two type handles for equality, or that hType2 is a derived class of hType1. +// The derived type check is used by the covariant returns feature. +// +// static +BOOL MetaSig::CompareTypeHandles(TypeHandle hType1, TypeHandle hType2, BOOL allowDerivedClass) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + PRECONDITION(!hType1.IsNull() && !hType2.IsNull()); + } + CONTRACTL_END; + + if (hType1 == hType2) + return TRUE; + + if (!allowDerivedClass) + return FALSE; + + if (hType1.IsNull() || hType2.IsValueType()) + { + return FALSE; + } + + hType2 = hType2.GetParent(); + + while (!hType2.IsNull()) + { + if (hType1 == hType2) + return TRUE; + hType2 = hType2.GetParent(); + } + + return FALSE; +} + +//--------------------------------------------------------------------------------------- +// +// Check if a type signature is eligible to be used with derived type signature comparison +// and if so, return TRUE if the type is eligible. +// Inputs: +// - pSig, pEndSig, pModule : Input type signature and module to check for eligibility. +// - isBaseTypeSig : Flag indicating whether the input signature should be treated +// as that of a base type or a derived type. +// Outputs: +// - pTypeDefToken, ppTypeDefModule : TypeDef token and module of the type in the input signature +// - pParentTypeDefOrRefOrSpecToken : Base type token if the input signature is treated as +// that of a derived type. This can be a TypeDef/TypeRef/TypeSpec. +// +// static +BOOL MetaSig::IsEligibleForDerivedTypeSignatureComparison( + PCCOR_SIGNATURE pSig, + PCCOR_SIGNATURE pEndSig, + Module* pModule, + BOOL isBaseTypeSig, + mdToken* pTypeDefToken, /* = NULL */ + Module** ppTypeDefModule, /* = NULL */ + mdToken* pParentTypeDefOrRefOrSpecToken) /* = NULL */ +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + } + CONTRACTL_END; + + CorElementType elementType = ELEMENT_TYPE_MAX; + + IfFailThrow(CorSigUncompressElementType_EndPtr(pSig, pEndSig, &elementType)); + + // System.Object is always eligible as a base type since all reference types derive from it + if (isBaseTypeSig && elementType == ELEMENT_TYPE_OBJECT) + { + return TRUE; + } + + if (elementType == ELEMENT_TYPE_GENERICINST) + { + IfFailThrow(CorSigUncompressElementType_EndPtr(pSig, pEndSig, &elementType)); + } + + // Only classes are eligible (no inheritance with value types) + if (elementType != ELEMENT_TYPE_CLASS) + { + return FALSE; + } + + mdToken typeRefOrDefToken; + IfFailThrow(CorSigUncompressToken_EndPtr(pSig, pEndSig, &typeRefOrDefToken)); + + // Ensure we are working with the typedef token + mdToken typeDefToken; + Module* pFoundModule; + if (!ClassLoader::ResolveTokenToTypeDefThrowing(pModule, typeRefOrDefToken, &pFoundModule, &typeDefToken)) + { + return FALSE; + } + + mdToken parentTypeDefOrRefOrSpecToken = mdTokenNil; + if (!isBaseTypeSig) + { + DWORD attr; + IfFailThrow(pFoundModule->GetMDImport()->GetTypeDefProps(typeDefToken, &attr, &parentTypeDefOrRefOrSpecToken)); + + // Check the validity of the parent type token if this is a signature of a derived type. + if (!pFoundModule->GetMDImport()->IsValidToken(parentTypeDefOrRefOrSpecToken)) + { + return FALSE; + } + } + + if (ppTypeDefModule != NULL) + *ppTypeDefModule = pFoundModule; + if (pTypeDefToken != NULL) + *pTypeDefToken = typeDefToken; + if (pParentTypeDefOrRefOrSpecToken != NULL) + *pParentTypeDefOrRefOrSpecToken = parentTypeDefOrRefOrSpecToken; + + return TRUE; +} + +//--------------------------------------------------------------------------------------- +// +// Compute the base type token (it will either be a typedef or typeref token), and return the +// module where that base type token is declared. +// +// static +BOOL MetaSig::GetBaseTypeTokenAndModule( + mdToken tk, + Module* pModule, + mdToken* pBaseTypeDefOrRefToken, + Module** ppBaseTypeTokenModule) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + PRECONDITION(CheckPointer(pModule)); + PRECONDITION(CheckPointer(pBaseTypeDefOrRefToken)); + PRECONDITION(CheckPointer(ppBaseTypeTokenModule)); + PRECONDITION(TypeFromToken(tk) == mdtTypeRef || TypeFromToken(tk) == mdtTypeDef); + MODE_ANY; + } + CONTRACTL_END; + + // Ensure we are working with the typedef token + mdToken typeDefToken; + Module* pFoundModule; + if (!ClassLoader::ResolveTokenToTypeDefThrowing(pModule, tk, &pFoundModule, &typeDefToken)) + return FALSE; + + DWORD attr; + mdToken tkTypeParent; + IfFailThrow(pFoundModule->GetMDImport()->GetTypeDefProps(typeDefToken, &attr, &tkTypeParent)); + + if (!pFoundModule->GetMDImport()->IsValidToken(tkTypeParent)) + return FALSE; + + if (TypeFromToken(tkTypeParent) == mdtTypeSpec) + { + // If the base type token is a TypeSpec of a generic instantiation, extract the type definition token + + ULONG cbSig; + PCCOR_SIGNATURE pSig; + IfFailThrow(pFoundModule->GetMDImport()->GetSigFromToken(tkTypeParent, &cbSig, &pSig)); + + PCCOR_SIGNATURE pEndSig = pSig + cbSig; + CorElementType elementType = ELEMENT_TYPE_MAX; + + IfFailThrow(CorSigUncompressElementType_EndPtr(pSig, pEndSig, &elementType)); + if (elementType == ELEMENT_TYPE_GENERICINST) + { + IfFailThrow(CorSigUncompressElementType_EndPtr(pSig, pEndSig, &elementType)); + } + + if (elementType != ELEMENT_TYPE_CLASS) + return FALSE; + + IfFailThrow(CorSigUncompressToken_EndPtr(pSig, pEndSig, pBaseTypeDefOrRefToken)); + *ppBaseTypeTokenModule = pFoundModule; + + _ASSERTE(TypeFromToken(*pBaseTypeDefOrRefToken) == mdtTypeRef || TypeFromToken(*pBaseTypeDefOrRefToken) == mdtTypeDef); + _ASSERTE(pFoundModule->GetMDImport()->IsValidToken(*pBaseTypeDefOrRefToken)); + + return TRUE; + } + else if (TypeFromToken(tkTypeParent) == mdtTypeRef || TypeFromToken(tkTypeParent) == mdtTypeDef) + { + *pBaseTypeDefOrRefToken = tkTypeParent; + *ppBaseTypeTokenModule = pFoundModule; + return TRUE; + } + + return FALSE; +} + +//------------------------------------------------------------------ +// Extract the base type's signature and stubstitution from the second type signature +// and recompare it with the first type's signature. +//------------------------------------------------------------------ +// static +BOOL MetaSig::ComputeBaseTypeAndCompareElementType( + PCCOR_SIGNATURE & pSig1, + PCCOR_SIGNATURE & pSig2, + PCCOR_SIGNATURE pEndSig1, + PCCOR_SIGNATURE pEndSig2, + Module * pModule1, + Module * pModule2, + const Substitution * pSubst1, + const Substitution * pSubst2, + TokenPairList* pVisited) // = NULL +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + INJECT_FAULT(COMPlusThrowOM()); + MODE_ANY; + } + CONTRACTL_END; + + // Quick check of Type1 for eligibility before starting to traverse base type chain in Type2 + if (!IsEligibleForDerivedTypeSignatureComparison(pSig1, pEndSig1, pModule1, TRUE)) + { + return FALSE; + } + + // Now a quick check of Type2 for eligibility, and if eligible, compute the TypeDef module of the current type in pSig2, as well + // as the base type token (which can be a TypeRef/TypeDef/TypeSpec) + Module* pTypeDefModule; + mdToken parentTypeDefOrRefOrSpecToken; + if (!IsEligibleForDerivedTypeSignatureComparison(pSig2, pEndSig2, pModule2, FALSE, NULL, &pTypeDefModule, &parentTypeDefOrRefOrSpecToken)) + { + return FALSE; + } + + // We need to check if the signature of Type2 is that of a generic type + // and if so, insert its generic instantiation arguments to the end of the substitution chain. + // Doing so will enable type signature comparison to traverse the generic stubstitution + // chain correctly while traversing the base type hierarchy of Type2. + // The instantiation arguments substitution have to be added as the leaf node of the + // substitution chain, which is why we perform the NULL check on the substitution + + const Substitution* pCurrentSubstChain = pSubst2; + + Substitution leafSubstFromGenericArgs; + if (pSubst2 == NULL || pSubst2->GetInst().IsNull()) + { + CorElementType et; + SigParser parser(pSig2, (DWORD)(pEndSig2 - pSig2)); + IfFailThrow(parser.GetElemType(&et)); + if (et == ELEMENT_TYPE_GENERICINST) + { + IfFailThrow(parser.SkipExactlyOne()); // Skip generic type definition signature + IfFailThrow(parser.GetData(NULL)); // Skip number of generic arguments + + leafSubstFromGenericArgs = Substitution(pModule2, SigPointer(parser.GetPtr()), NULL); + + // Set the current substitution chain to the leaf node we just created. + pCurrentSubstChain = &leafSubstFromGenericArgs; + } + } + + Substitution parentTypeSubst; + SigBuilder parentTypeSigBuilder; + + // If the parent type token is a TypeSpec token, we need to load the substitution from the signature and + // chain it to the existing substitution chain. This is necessary to ensure proper comparisons + // for generic instantiation arguments while performing comparison using one of the base type's signatures. + + if (TypeFromToken(parentTypeDefOrRefOrSpecToken) == mdtTypeSpec) + { + ULONG cbParentTypeSig; + PCCOR_SIGNATURE pParentTypeSig; + IfFailThrow(pTypeDefModule->GetMDImport()->GetSigFromToken(parentTypeDefOrRefOrSpecToken, &cbParentTypeSig, &pParentTypeSig)); + + parentTypeSigBuilder.AppendSignature(pParentTypeSig, pParentTypeSig + cbParentTypeSig); + parentTypeSubst = Substitution(parentTypeDefOrRefOrSpecToken, pTypeDefModule, pCurrentSubstChain); + } + else if (TypeFromToken(parentTypeDefOrRefOrSpecToken) == mdtTypeDef || TypeFromToken(parentTypeDefOrRefOrSpecToken) == mdtTypeRef) + { + // We need to special case type System.Object since it has its own element type. We don't need to do the same for type String + // because it's a sealed type, and no other class can derive from it. Without this special casing, we'll end up with a comparison + // between a ELEMENT_TYPE_OBJECT and a ELEMENT_TYPE_CLASS respresentation of object, which we'll have to special case in the + // implementation of MetaSig::CompareElementType() by checking the type token following ELEMENT_TYPE_CLASS (possible, but adds + // unnecessary complexity). + + Module* pResolvedModule; + mdTypeDef resolvedTypeDefToken; + BOOL resolvedToken = ClassLoader::ResolveTokenToTypeDefThrowing(pTypeDefModule, parentTypeDefOrRefOrSpecToken, &pResolvedModule, &resolvedTypeDefToken); + + if (resolvedToken && pResolvedModule == g_pObjectClass->GetModule() && resolvedTypeDefToken == g_pObjectClass->GetCl()) + { + parentTypeSigBuilder.AppendElementType(ELEMENT_TYPE_OBJECT); + } + else + { + parentTypeSigBuilder.AppendElementType(ELEMENT_TYPE_CLASS); + parentTypeSigBuilder.AppendToken(parentTypeDefOrRefOrSpecToken); + } + + parentTypeSubst = (pCurrentSubstChain == NULL ? Substitution() : Substitution(*pCurrentSubstChain)); + } + else + { + return FALSE; + } + + DWORD cbParentTypeSig; + PCCOR_SIGNATURE pParentTypeSig = (PCCOR_SIGNATURE)parentTypeSigBuilder.GetSignature(&cbParentTypeSig); + PCCOR_SIGNATURE pParentTypeSigEnd = pParentTypeSig + cbParentTypeSig; + + // + // Given that we're going to restart the current type comparaison between Type1 and the base type of Type2, and + // given that the signature pointers for both types are passed by reference to get updated during each call to + // CompareElementType(), we need to skip one element from the original signature of Type2. + // + SigParser parser = SigParser(pSig2); + IfFailThrow(parser.SkipExactlyOne()); + pSig2 = parser.GetPtr(); + + return CompareElementType( + pSig1, + pParentTypeSig, + pEndSig1, + pParentTypeSigEnd, + pModule1, + pTypeDefModule, + pSubst1, + parentTypeSubst.GetInst().IsNull() ? NULL : &parentTypeSubst, + TRUE, + pVisited); +} + //--------------------------------------------------------------------------------------- // // Compare the next elements in two sigs. @@ -3582,6 +3922,7 @@ MetaSig::CompareElementType( Module * pModule2, const Substitution * pSubst1, const Substitution * pSubst2, + BOOL allowDerivedClass, TokenPairList * pVisited) // = NULL { CONTRACTL @@ -3591,7 +3932,10 @@ MetaSig::CompareElementType( INJECT_FAULT(COMPlusThrowOM()); MODE_ANY; } - CONTRACTL_END + CONTRACTL_END; + + PCCOR_SIGNATURE pSig1Start = pSig1; + PCCOR_SIGNATURE pSig2Start = pSig2; redo: // We jump here if the Type was a ET_CMOD prefix. @@ -3626,6 +3970,7 @@ MetaSig::CompareElementType( pSubst2->GetModule(), pSubst1, pSubst2->GetNext(), + allowDerivedClass, pVisited); } @@ -3653,6 +3998,7 @@ MetaSig::CompareElementType( pModule2, pSubst1->GetNext(), pSubst2, + allowDerivedClass, pVisited); } @@ -3691,21 +4037,21 @@ MetaSig::CompareElementType( { if ((Type1 == ELEMENT_TYPE_INTERNAL) || (Type2 == ELEMENT_TYPE_INTERNAL)) { - TypeHandle hInternal; + TypeHandle hType1, hType2; CorElementType eOtherType; Module * pOtherModule; // One type is already loaded, collect all the necessary information to identify the other type. if (Type1 == ELEMENT_TYPE_INTERNAL) { - IfFailThrow(CorSigUncompressPointer_EndPtr(pSig1, pEndSig1, (void **)&hInternal)); + IfFailThrow(CorSigUncompressPointer_EndPtr(pSig1, pEndSig1, (void **)&hType1)); eOtherType = Type2; pOtherModule = pModule2; } else { - IfFailThrow(CorSigUncompressPointer_EndPtr(pSig2, pEndSig2, (void **)&hInternal)); + IfFailThrow(CorSigUncompressPointer_EndPtr(pSig2, pEndSig2, (void **)&hType2)); eOtherType = Type1; pOtherModule = pModule1; @@ -3716,11 +4062,30 @@ MetaSig::CompareElementType( { case ELEMENT_TYPE_OBJECT: { - return (hInternal.AsMethodTable() == g_pObjectClass); + if (Type1 == ELEMENT_TYPE_INTERNAL) + { + // Type2 is ELEMENT_TYPE_OBJECT. Return true only if Type1 is also type object. + return hType1.AsMethodTable() == g_pObjectClass; + } + else + { + // Type1 is ELEMENT_TYPE_OBJECT. Return true if Type2 is type System.Object or any other class + // if allowDerivedClass is TRUE. + if (hType2.AsMethodTable() == g_pObjectClass) + { + return TRUE; + } + else + { + return allowDerivedClass ? CompareTypeHandles(TypeHandle(g_pObjectClass), hType2, TRUE) : FALSE; + } + } } case ELEMENT_TYPE_STRING: { - return (hInternal.AsMethodTable() == g_pStringClass); + return Type1 == ELEMENT_TYPE_INTERNAL ? + hType1.AsMethodTable() == g_pStringClass : + hType2.AsMethodTable() == g_pStringClass; } case ELEMENT_TYPE_VALUETYPE: case ELEMENT_TYPE_CLASS: @@ -3729,20 +4094,23 @@ MetaSig::CompareElementType( if (Type1 == ELEMENT_TYPE_INTERNAL) { IfFailThrow(CorSigUncompressToken_EndPtr(pSig2, pEndSig2, &tkOther)); + hType2 = ClassLoader::LoadTypeDefOrRefThrowing( + pOtherModule, + tkOther, + ClassLoader::ReturnNullIfNotFound, + ClassLoader::FailIfUninstDefOrRef); } else { IfFailThrow(CorSigUncompressToken_EndPtr(pSig1, pEndSig1, &tkOther)); + hType1 = ClassLoader::LoadTypeDefOrRefThrowing( + pOtherModule, + tkOther, + ClassLoader::ReturnNullIfNotFound, + ClassLoader::FailIfUninstDefOrRef); } - TypeHandle hOtherType; - - hOtherType = ClassLoader::LoadTypeDefOrRefThrowing( - pOtherModule, - tkOther, - ClassLoader::ReturnNullIfNotFound, - ClassLoader::FailIfUninstDefOrRef); - return (hInternal == hOtherType); + return CompareTypeHandles(hType1, hType2, allowDerivedClass); } default: { @@ -3752,7 +4120,31 @@ MetaSig::CompareElementType( } else { - return FALSE; // types must be the same + if (allowDerivedClass) + { + // Obvious case: string derives from object. + if (Type1 == ELEMENT_TYPE_OBJECT && Type2 == ELEMENT_TYPE_STRING) + { + return TRUE; + } + + // Reset pSig1 and pSig2 to their initial position (Note that their values get updated during the + // recursive calls). + pSig1 = pSig1Start; + pSig2 = pSig2Start; + return ComputeBaseTypeAndCompareElementType( + pSig1, + pSig2, + pEndSig1, + pEndSig2, + pModule1, + pModule2, + pSubst1, + pSubst2, + pVisited); + } + + return FALSE; } } @@ -3836,6 +4228,7 @@ MetaSig::CompareElementType( pModule2, pSubst1, pSubst2, + FALSE, pVisited)) { return FALSE; @@ -3851,7 +4244,77 @@ MetaSig::CompareElementType( IfFailThrow(CorSigUncompressToken_EndPtr(pSig1, pEndSig1, &tk1)); IfFailThrow(CorSigUncompressToken_EndPtr(pSig2, pEndSig2, &tk2)); - return CompareTypeTokens(tk1, tk2, pModule1, pModule2, pVisited); + if (CompareTypeTokens(tk1, tk2, pModule1, pModule2, pVisited)) + { + return TRUE; + } + + if (allowDerivedClass) + { + // + // We need to check if Type2 derives from Type1. Note that if Type1 is a generic type, + // we cannot check for inheritance here because we need to properly keep track of substitutions. + // + // Here's an example: + // class Class0 { } + // class Class1 : Class0 { } + // class Class2 : Class1 { } + // class Class3 : Class2 { } + // class Class4 : Class3{ } + // + // Here, we need to check if Class4 derives from Class0 + // + // In that example, if we just look at the typedef tokens for Class0 and Class4, and traverse the + // parent chain of Class4 to check if it derives from Class0, we would be always returning true, which + // is not necessarily correct all the times. + // Here's a counter example: if Class2 was declared as 'Class2 : Class1', + // then Class4 would be deriving from Class0, and not from Class0. + // + // Therefore, we need to keep track of the substitutions: + // A -> ARG1 -> T -> int32 + // B -> ARG2 -> int16 + // + // To handle that case, we need to compute the base type *AND* base type substitution chain of type2, and + // recompare that with type1. If type1 is generic, we'll return return FALSE here, so that we can properly + // handle this scenario under ELEMENT_TYPE_GENERICINST. + // + + // First, check if Type1 is eligible for covariant returns + + mdToken typeDefToken1; + Module* pTypeDefModule1; + if (!IsEligibleForDerivedTypeSignatureComparison(pSig1Start, pEndSig1, pModule1, TRUE, &typeDefToken1, &pTypeDefModule1)) + { + return FALSE; + } + + // Second, check if Type1 is generic. If so, we'll return FALSE here, and have that handled under ELEMENT_TYPE_GENERICINST + + HENUMInternal hEnumGenericPars; + IfFailThrow(pTypeDefModule1->GetMDImport()->EnumInit(mdtGenericParam, typeDefToken1, &hEnumGenericPars)); + if (pTypeDefModule1->GetMDImport()->EnumGetCount(&hEnumGenericPars) != 0) + { + return FALSE; + } + + // Finally, walk the base type chain of Type2 to check if it derives from Type1. At this point, we don't need to + // worry about generic substitutions because we know that Type1 is non-generic. A simple token-based comparison + // will yield the correct result here. + + mdToken baseType2Token = tk2; + Module* pBaseType2Module = pModule2; + while (GetBaseTypeTokenAndModule(tk2, pModule2, &baseType2Token, &pBaseType2Module) && !(baseType2Token == tk2 && pBaseType2Module == pModule2)) + { + tk2 = baseType2Token; + pModule2 = pBaseType2Module; + if (CompareTypeTokens(tk1, tk2, pModule1, pModule2, pVisited)) + { + return TRUE; + } + } + } + + return FALSE; } case ELEMENT_TYPE_FNPTR: @@ -3895,6 +4358,7 @@ MetaSig::CompareElementType( pModule2, pSubst1, pSubst2, + FALSE, &newVisited)) { return FALSE; @@ -3923,9 +4387,28 @@ MetaSig::CompareElementType( pModule2, pSubst1, pSubst2, + allowDerivedClass, &newVisitedAlwaysForbidden)) { - return FALSE; + if (!allowDerivedClass) + { + return FALSE; + } + + // Reset pSig1 and pSig2 to their initial position (Note that their values get updated during the + // recursive calls). + pSig1 = pSig1Start; + pSig2 = pSig2Start; + return ComputeBaseTypeAndCompareElementType( + pSig1, + pSig2, + pEndSig1, + pEndSig2, + pModule1, + pModule2, + pSubst1, + pSubst2, + &newVisitedAlwaysForbidden); } DWORD argCnt1; @@ -3948,6 +4431,7 @@ MetaSig::CompareElementType( pModule2, pSubst1, pSubst2, + FALSE, &newVisited)) { return FALSE; @@ -3976,6 +4460,7 @@ MetaSig::CompareElementType( pModule2, pSubst1, pSubst2, + FALSE, pVisited)) { return FALSE; @@ -4056,7 +4541,7 @@ MetaSig::CompareElementType( IfFailThrow(CorSigUncompressPointer_EndPtr(pSig1, pEndSig1, (void **)&hType1)); IfFailThrow(CorSigUncompressPointer_EndPtr(pSig2, pEndSig2, (void **)&hType2)); - return (hType1 == hType2); + return CompareTypeHandles(hType1, hType2, allowDerivedClass); } } // switch // Unreachable @@ -4130,6 +4615,7 @@ MetaSig::CompareTypeDefsUnderSubstitutions( pSubst2->GetModule(), pSubst1->GetNext(), pSubst2->GetNext(), + FALSE, pVisited)) { return FALSE; @@ -4237,7 +4723,7 @@ MetaSig::CompareMethodSigsNT( HRESULT hr = S_OK; EX_TRY { - if (CompareMethodSigs(pSignature1, cSig1, pModule1, pSubst1, pSignature2, cSig2, pModule2, pSubst2, pVisited)) + if (CompareMethodSigs(pSignature1, cSig1, pModule1, pSubst1, pSignature2, cSig2, pModule2, pSubst2, FALSE, pVisited)) hr = S_OK; else hr = S_FALSE; @@ -4262,6 +4748,7 @@ MetaSig::CompareMethodSigs( DWORD cSig2, Module * pModule2, const Substitution * pSubst2, + BOOL allowCovariantReturn, TokenPairList * pVisited) //= NULL { CONTRACTL @@ -4366,6 +4853,7 @@ MetaSig::CompareMethodSigs( pModule2, pSubst1, pSubst2, + i == 0 && allowCovariantReturn, pVisited)) { return FALSE; @@ -4391,6 +4879,7 @@ MetaSig::CompareMethodSigs( pModule2, pSubst1, pSubst2, + i == 0 && allowCovariantReturn, pVisited)) { return FALSE; @@ -4431,7 +4920,7 @@ BOOL MetaSig::CompareFieldSigs( pEndSig1 = pSig1 + cSig1; pEndSig2 = pSig2 + cSig2; - return(CompareElementType(++pSig1, ++pSig2, pEndSig1, pEndSig2, pModule1, pModule2, NULL, NULL, pVisited)); + return(CompareElementType(++pSig1, ++pSig2, pEndSig1, pEndSig2, pModule1, pModule2, NULL, NULL, FALSE, pVisited)); } #ifndef DACCESS_COMPILE @@ -4673,7 +5162,7 @@ BOOL MetaSig::CompareTypeDefOrRefOrSpec(Module *pModule1, mdToken tok1, ULONG cSig1,cSig2; IfFailThrow(pInternalImport1->GetTypeSpecFromToken(tok1, &pSig1, &cSig1)); IfFailThrow(pInternalImport2->GetTypeSpecFromToken(tok2, &pSig2, &cSig2)); - return MetaSig::CompareElementType(pSig1,pSig2,pSig1+cSig1,pSig2+cSig2,pModule1,pModule2,pSubst1,pSubst2,pVisited); + return MetaSig::CompareElementType(pSig1, pSig2, pSig1 + cSig1, pSig2 + cSig2, pModule1, pModule2, pSubst1, pSubst2, FALSE, pVisited); } // MetaSig::CompareTypeDefOrRefOrSpec /* static */ @@ -5258,6 +5747,7 @@ MetaSig::GetUnmanagedCallingConvention( *pPinvokeMapOut = (CorPinvokeMap)0; return TRUE; } +#endif // #ifndef DACCESS_COMPILE //--------------------------------------------------------------------------------------- // @@ -5358,8 +5848,6 @@ void Substitution::DeleteChain() delete this; } -#endif // #ifndef DACCESS_COMPILE - //--------------------------------------------------------------------------------------- // // static diff --git a/src/coreclr/src/vm/siginfo.hpp b/src/coreclr/src/vm/siginfo.hpp index e294239670520f..a0c3de4533852e 100644 --- a/src/coreclr/src/vm/siginfo.hpp +++ b/src/coreclr/src/vm/siginfo.hpp @@ -970,12 +970,20 @@ class MetaSig //------------------------------------------------------------------ CorElementType GetByRefType(TypeHandle* pTy) const; + //------------------------------------------------------------------ + // Compare two type handles for equality. If the two types are not equal, and allowDerivedClass + // is TRUE, return true if hType2 derives from hType1. This inheritance check is used to allow + // for covariant return types on MethodImpls. + //------------------------------------------------------------------ + static BOOL CompareTypeHandles(TypeHandle hType1, TypeHandle hType2, BOOL allowDerivedClass); + + + //------------------------------------------------------------------ // Compare types in two signatures, first applying // - optional substitutions pSubst1 and pSubst2 // to class type parameters (E_T_VAR) in the respective signatures - static - BOOL - CompareElementType( + //------------------------------------------------------------------ + static BOOL CompareElementType( PCCOR_SIGNATURE & pSig1, PCCOR_SIGNATURE & pSig2, PCCOR_SIGNATURE pEndSig1, @@ -984,6 +992,7 @@ class MetaSig Module * pModule2, const Substitution * pSubst1, const Substitution * pSubst2, + BOOL allowDerivedClass, TokenPairList * pVisited = NULL); @@ -1002,15 +1011,16 @@ class MetaSig // Compare two complete method signatures, first applying optional substitutions pSubst1 and pSubst2 // to class type parameters (E_T_VAR) in the respective signatures static BOOL CompareMethodSigs( - PCCOR_SIGNATURE pSig1, - DWORD cSig1, - Module* pModule1, + PCCOR_SIGNATURE pSig1, + DWORD cSig1, + Module* pModule1, const Substitution* pSubst1, - PCCOR_SIGNATURE pSig2, - DWORD cSig2, - Module* pModule2, + PCCOR_SIGNATURE pSig2, + DWORD cSig2, + Module* pModule2, const Substitution* pSubst2, - TokenPairList *pVisited = NULL + BOOL allowCovariantReturn, + TokenPairList* pVisited = NULL ); // Nonthrowing version of CompareMethodSigs @@ -1057,6 +1067,53 @@ class MetaSig mdMethodDef tok2); //declared method private: + //------------------------------------------------------------------ + // Check if a type signature is eligible to be used with derived type signature comparisons + // and if so, return TRUE if the type is eligible. + // Inputs: + // - pSig, pEndSig, pModule : Input type signature and module to check for eligibility. + // - isBaseTypeSig : Flag indicating whether the input signature should be treated + // as that of a base type or a derived type. + // Outputs: + // - pTypeDefToken, ppTypeDefModule : TypeDef token and module of the type in the input signature + // - pParentTypeDefOrRefOrSpecToken : Base type token if the input signature is treated as + // that of a derived type. This can be a TypeDef/TypeRef/TypeSpec. + //------------------------------------------------------------------ + static BOOL IsEligibleForDerivedTypeSignatureComparison( + PCCOR_SIGNATURE pSig, + PCCOR_SIGNATURE pEndSig, + Module* pModule, + BOOL isBaseTypeSig, + mdToken* pTypeDefToken = NULL, + Module** ppTypeDefModule = NULL, + mdToken* pParentTypeDefOrRefOrSpecToken = NULL); + + //------------------------------------------------------------------ + // Compute the base type token (it will either be a typedef or typeref token), and returns the + // module where that base type token is declared. + // The input token has to either be a TypeRef or TypeDef token. + //------------------------------------------------------------------ + static BOOL GetBaseTypeTokenAndModule( + mdToken tk, + Module* pModule, + mdToken* pBaseTypeDefOrRefToken, + Module** ppBaseTypeTokenModule); + + //------------------------------------------------------------------ + // Extract the base type's signature and stubstitution from the second type signature + // and recompare it with the first type's signature. + //------------------------------------------------------------------ + static BOOL ComputeBaseTypeAndCompareElementType( + PCCOR_SIGNATURE & pSig1, + PCCOR_SIGNATURE & pSig2, + PCCOR_SIGNATURE pEndSig1, + PCCOR_SIGNATURE pEndSig2, + Module * pModule1, + Module * pModule2, + const Substitution * pSubst1, + const Substitution * pSubst2, + TokenPairList* pVisited = NULL); + static BOOL CompareVariableConstraints(const Substitution *pSubst1, Module *pModule1, mdGenericParam tok1, //overriding const Substitution *pSubst2, diff --git a/src/coreclr/src/vm/wellknownattributes.h b/src/coreclr/src/vm/wellknownattributes.h index de71eb459f90cf..8401f233cd0c56 100644 --- a/src/coreclr/src/vm/wellknownattributes.h +++ b/src/coreclr/src/vm/wellknownattributes.h @@ -35,6 +35,7 @@ enum class WellKnownAttribute : DWORD UnmanagedFunctionPointer, ThreadStatic, WinRTMarshalingBehaviorAttribute, + ValidateMethodImplRemainsInEffectAttribute, CountOfWellKnownAttributes }; @@ -99,6 +100,8 @@ inline const char *GetWellKnownAttributeName(WellKnownAttribute attribute) return "System.ThreadStaticAttribute"; case WellKnownAttribute::WinRTMarshalingBehaviorAttribute: return "Windows.Foundation.Metadata.MarshalingBehaviorAttribute"; + case WellKnownAttribute::ValidateMethodImplRemainsInEffectAttribute: + return "System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute"; case WellKnownAttribute::CountOfWellKnownAttributes: default: break; // Silence compiler warnings diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il new file mode 100644 index 00000000000000..5328d287bd74ad --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il @@ -0,0 +1,311 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib { } +.assembly InterfaceReturns { } + +.class interface public auto ansi abstract IA { } +.class interface public auto ansi abstract IB implements IA { } +.class interface public auto ansi abstract IC implements IB { } +.class interface public auto ansi abstract IGenRetType { } + +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 implements class IGenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 implements class IGenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 implements IC { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + +.class public auto ansi beforefieldinit NonGenThroughGen1 implements class IC { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + +.class public auto ansi beforefieldinit BaseTest +{ + .method public hidebysig newslot virtual instance object MyFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class IB MyFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class IB GenToNonGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class IB NonGenThroughGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class IGenRetType GenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class IGenRetType> GenFunc() + { + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test1 extends class BaseTest +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride() + { + .override method instance class IB class BaseTest::NonGenThroughGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test2 extends class BaseTest +{ + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride() + { + .override method instance class IB class BaseTest::GenToNonGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test3 extends class BaseTest +{ + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1() + { + .override method instance class IGenRetType class BaseTest::GenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test4 extends class BaseTest +{ + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2() + { + .override method instance class IGenRetType> class BaseTest::GenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test5 extends class BaseTest +{ + .method public hidebysig newslot virtual instance class IGenRetType NewFunc1() + { + .override method instance object class BaseTest::MyFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test6 extends class BaseTest +{ + .method public hidebysig newslot virtual instance class IC NewFunc2() + { + .override method instance class IB class BaseTest::MyFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + newobj instance void class Test1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + newobj instance void class Test2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + newobj instance void class Test3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + newobj instance void class Test4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + newobj instance void class Test5::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest6() noinlining + { + newobj instance void class Test6::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." + call void [System.Console]System.Console::WriteLine(string) + leave.s T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." + call void [System.Console]System.Console::WriteLine(string) + leave.s T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." + call void [System.Console]System.Console::WriteLine(string) + leave.s T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." + call void [System.Console]System.Console::WriteLine(string) + leave.s T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + call void [System.Console]System.Console::WriteLine(string) + leave.s T6 + } + 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 T6 + } + + T6: + .try + { + call void CMain::RunTest6() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test6." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method CMain::.ctor + +} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.ilproj new file mode 100644 index 00000000000000..be204aa3511097 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il new file mode 100644 index 00000000000000..df136fbada4524 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il @@ -0,0 +1,271 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib { } +.assembly InterfaceReturns { } + +.class interface public auto ansi abstract IA { } +.class interface public auto ansi abstract IB implements IA { } +.class interface public auto ansi abstract IC implements IB { } +.class interface public auto ansi abstract IGenRetType { } + +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 implements class IGenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 implements class IGenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 implements IC { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + +.class public auto ansi beforefieldinit NonGenThroughGen1 implements class IC { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + +.class public auto ansi beforefieldinit BaseTest +{ + .method public hidebysig newslot virtual instance class IGenRetType MyFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenericDerived4 GenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenDerive3 GenFunc() + { + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test1 extends class BaseTest +{ + .method public hidebysig newslot virtual instance class IB NonGenThroughGenOverride() + { + .override method instance class NonGenThroughGen4 class BaseTest::NonGenThroughGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test2 extends class BaseTest +{ + .method public hidebysig newslot virtual instance class IB GenToNonGenOverride() + { + .override method instance class GenToNonGen3 class BaseTest::GenToNonGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test3 extends class BaseTest +{ + .method public hidebysig newslot virtual instance class IGenRetType NewGenFunc1() + { + .override method instance class NonGenericDerived4 class BaseTest::GenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test4 extends class BaseTest +{ + .method public hidebysig newslot virtual instance class IGenRetType> NewGenFunc2() + { + .override method instance class GenDerive3 class BaseTest::GenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test5 extends class BaseTest +{ + .method public hidebysig newslot virtual instance object NewFunc1() + { + .override method instance class IGenRetType class BaseTest::MyFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + newobj instance void class Test1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + newobj instance void class Test2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + newobj instance void class Test3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + newobj instance void class Test4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + newobj instance void class Test5::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." + call void [System.Console]System.Console::WriteLine(string) + leave.s T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." + call void [System.Console]System.Console::WriteLine(string) + leave.s T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." + call void [System.Console]System.Console::WriteLine(string) + leave.s T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." + call void [System.Console]System.Console::WriteLine(string) + leave.s T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method CMain::.ctor + +} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.ilproj new file mode 100644 index 00000000000000..3b6bc58d956513 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il new file mode 100644 index 00000000000000..d92fa42a24f6b8 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il @@ -0,0 +1,272 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib { } +.assembly InterfaceReturns { } + +.class public auto ansi beforefieldinit A { } +.class public auto ansi beforefieldinit B extends A { } +.class public auto ansi beforefieldinit C extends B { } + +.class public auto ansi beforefieldinit GenRetType { } + +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends class C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + +.class interface public auto ansi abstract BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType MyFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenericDerived4 GenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenDerive3 GenFunc() + { + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test1 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride() + { + .override method instance class NonGenThroughGen4 class BaseTest::NonGenThroughGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test2 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class B GenToNonGenOverride() + { + .override method instance class GenToNonGen3 class BaseTest::GenToNonGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test3 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1() + { + .override method instance class NonGenericDerived4 class BaseTest::GenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test4 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2() + { + .override method instance class GenDerive3 class BaseTest::GenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test5 implements class BaseTest +{ + .method public hidebysig newslot virtual instance object NewFunc1() + { + .override method instance class GenRetType class BaseTest::MyFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + newobj instance void class Test1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + newobj instance void class Test2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + newobj instance void class Test3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + newobj instance void class Test4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + newobj instance void class Test5::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." + call void [System.Console]System.Console::WriteLine(string) + leave.s T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." + call void [System.Console]System.Console::WriteLine(string) + leave.s T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." + call void [System.Console]System.Console::WriteLine(string) + leave.s T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." + call void [System.Console]System.Console::WriteLine(string) + leave.s T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method CMain::.ctor + +} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.ilproj new file mode 100644 index 00000000000000..01bdabf789e477 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il new file mode 100644 index 00000000000000..ca5824ea824226 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il @@ -0,0 +1,272 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib { } +.assembly InterfaceReturns { } + +.class public auto ansi beforefieldinit A { } +.class public auto ansi beforefieldinit B extends A { } +.class public auto ansi beforefieldinit C extends B { } + +.class public auto ansi beforefieldinit GenRetType { } + +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends class C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + +.class interface public auto ansi abstract BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType MyFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenericDerived4 GenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenDerive3 GenFunc() + { + ldnull + ret + } +} + +.class interface public auto ansi abstract Test1 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride() + { + .override method instance class NonGenThroughGen4 class BaseTest::NonGenThroughGenFunc() + ldnull + ret + } +} + +.class interface public auto ansi abstract Test2 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class B GenToNonGenOverride() + { + .override method instance class GenToNonGen3 class BaseTest::GenToNonGenFunc() + ldnull + ret + } +} + +.class interface public auto ansi abstract Test3 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1() + { + .override method instance class NonGenericDerived4 class BaseTest::GenFunc() + ldnull + ret + } +} + +.class interface public auto ansi abstract Test4 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2() + { + .override method instance class GenDerive3 class BaseTest::GenFunc() + ldnull + ret + } +} + +.class interface public auto ansi abstract Test5 implements class BaseTest +{ + .method public hidebysig newslot virtual instance object NewFunc1() + { + .override method instance class GenRetType class BaseTest::MyFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + newobj instance void class Test1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + newobj instance void class Test2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + newobj instance void class Test3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + newobj instance void class Test4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + newobj instance void class Test5::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." + call void [System.Console]System.Console::WriteLine(string) + leave.s T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." + call void [System.Console]System.Console::WriteLine(string) + leave.s T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." + call void [System.Console]System.Console::WriteLine(string) + leave.s T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." + call void [System.Console]System.Console::WriteLine(string) + leave.s T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method CMain::.ctor + +} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.ilproj new file mode 100644 index 00000000000000..a514e3ab598aa2 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il new file mode 100644 index 00000000000000..e0da29eccb9f01 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il @@ -0,0 +1,276 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib { } +.assembly StructReturns { } + +.class public sealed auto ansi A extends [mscorlib]System.ValueType { } +.class public sealed auto ansi GenStruct extends [mscorlib]System.ValueType { } + + +.class public auto ansi C { } +.class public auto ansi GenRetType { } +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends class C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + + +.class public auto ansi beforefieldinit BaseType +{ + .method public hidebysig newslot virtual instance valuetype A MyFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance valuetype A GenToNonGen() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance valuetype A NonGenThroughGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance valuetype GenStruct MyGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance valuetype GenStruct> MyGenFunc() + { + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test1 extends class BaseType +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride() + { + .override method instance valuetype A class BaseType::NonGenThroughGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test2 extends class BaseType +{ + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride() + { + .override method instance valuetype A class BaseType::GenToNonGen() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test3 extends class BaseType +{ + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1() + { + .override method instance valuetype GenStruct class BaseType::MyGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test4 extends class BaseType +{ + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc1() + { + .override method instance valuetype GenStruct> class BaseType::MyGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test5 extends class BaseType +{ + .method public hidebysig newslot virtual instance class C NewFunc2() + { + .override method instance valuetype A class BaseType::MyFunc() + ldnull + ret + } +} + + + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + newobj instance void class Test1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + newobj instance void class Test2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + newobj instance void class Test3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + newobj instance void class Test4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + newobj instance void class Test5::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." + call void [System.Console]System.Console::WriteLine(string) + leave.s T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." + call void [System.Console]System.Console::WriteLine(string) + leave.s T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." + call void [System.Console]System.Console::WriteLine(string) + leave.s T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." + call void [System.Console]System.Console::WriteLine(string) + leave.s T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method CMain::.ctor + +} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.ilproj new file mode 100644 index 00000000000000..c04e576a800da2 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il new file mode 100644 index 00000000000000..a36b91e8a2b00f --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il @@ -0,0 +1,276 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib { } +.assembly StructReturns { } + +.class public sealed auto ansi A extends [mscorlib]System.ValueType { } +.class public sealed auto ansi GenStruct extends [mscorlib]System.ValueType { } + + +.class public auto ansi C { } +.class public auto ansi GenRetType { } +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends class C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + + +.class public auto ansi beforefieldinit BaseType +{ + .method public hidebysig newslot virtual instance class C MyFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGen() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenericDerived4 MyGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenDerive3 MyGenFunc() + { + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test1 extends class BaseType +{ + .method public hidebysig newslot virtual instance valuetype A NonGenThroughGenOverride() + { + .override method instance class NonGenThroughGen4 class BaseType::NonGenThroughGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test2 extends class BaseType +{ + .method public hidebysig newslot virtual instance valuetype A GenToNonGenOverride() + { + .override method instance class GenToNonGen3 class BaseType::GenToNonGen() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test3 extends class BaseType +{ + .method public hidebysig newslot virtual instance valuetype GenStruct NewGenFunc1() + { + .override method instance class NonGenericDerived4 class BaseType::MyGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test4 extends class BaseType +{ + .method public hidebysig newslot virtual instance valuetype GenStruct> NewGenFunc1() + { + .override method instance class GenDerive3 class BaseType::MyGenFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test5 extends class BaseType +{ + .method public hidebysig newslot virtual instance valuetype A NewFunc2() + { + .override method instance class C class BaseType::MyFunc() + ldnull + ret + } +} + + + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + newobj instance void class Test1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + newobj instance void class Test2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + newobj instance void class Test3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + newobj instance void class Test4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + newobj instance void class Test5::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." + call void [System.Console]System.Console::WriteLine(string) + leave.s T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." + call void [System.Console]System.Console::WriteLine(string) + leave.s T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." + call void [System.Console]System.Console::WriteLine(string) + leave.s T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." + call void [System.Console]System.Console::WriteLine(string) + leave.s T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method CMain::.ctor + +} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.ilproj new file mode 100644 index 00000000000000..6219c833c18cab --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.il new file mode 100644 index 00000000000000..0388370550bc28 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.il @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly A{} + +.class public auto ansi beforefieldinit A { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.ilproj new file mode 100644 index 00000000000000..c4248224974169 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.il new file mode 100644 index 00000000000000..3a49d6fd3f9644 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.il @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern A{} +.assembly B{} + + +.class public auto ansi beforefieldinit B extends [A]A { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.ilproj new file mode 100644 index 00000000000000..5dafe94b9dbfe1 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.il new file mode 100644 index 00000000000000..ece5321703e258 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.il @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly extern B{} +.assembly C{} + +.class public auto ansi beforefieldinit C extends [B]B { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.ilproj new file mode 100644 index 00000000000000..f4c3d16fcfd0aa --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.il new file mode 100644 index 00000000000000..f23cc2e3f2e7f7 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.il @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly Dictionary{} + +.class public auto ansi beforefieldinit Dictionary { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.ilproj new file mode 100644 index 00000000000000..6e3dd6c0bf32ed --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.il new file mode 100644 index 00000000000000..7d70bf4fb86135 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.il @@ -0,0 +1,80 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib { } +.assembly extern A { } +.assembly extern B { } +.assembly extern GenRetType { } +.assembly extern Dictionary { } + +.assembly GenBaseType { } + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + + .method public hidebysig newslot virtual instance object MyFunc(string& res) + { + ldarg.0 + ldstr "object GenBaseType.MyFunc()" + stind.ref + newobj instance void [A]A::.ctor() + ret + } + .method public hidebysig newslot virtual instance class [B]B MyFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.MyFunc()" + stind.ref + newobj instance void [B]B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class [B]B GenToNonGen(string& res) + { + ldarg.0 + ldstr "B GenBaseType.GenToNonGen()" + stind.ref + newobj instance void [B]B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class [B]B NonGenThroughGenFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.NonGenThroughGenFunc()" + stind.ref + newobj instance void [B]B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class [GenRetType]GenRetType MyGenFunc(string& res) + { + ldarg.0 + ldstr "GenRetType GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class [GenRetType]GenRetType::.ctor() + ret + } + .method public hidebysig newslot virtual instance class [GenRetType]GenRetType> MyGenFunc(string& res) + { + ldarg.0 + ldstr "GenRetType> GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class [GenRetType]GenRetType>::.ctor() + ret + } + .method public hidebysig newslot virtual instance class [GenRetType]GenRetType TestNonGenericDerived(string& res) + { + ldarg.0 + ldstr "GenRetType GenBaseType.TestNonGenericDerived()" + stind.ref + newobj instance void class [GenRetType]GenRetType::.ctor() + ret + } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.ilproj new file mode 100644 index 00000000000000..92c1d500858832 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.il new file mode 100644 index 00000000000000..9678d6dda30015 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.il @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly extern GenRetType{} +.assembly GenDerive1{} + +.class public auto ansi beforefieldinit GenDerive1 extends class [GenRetType]GenRetType { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.ilproj new file mode 100644 index 00000000000000..b560c1792a242a --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.il new file mode 100644 index 00000000000000..b50fbfc783ea66 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.il @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly extern GenDerive1{} +.assembly extern Dictionary{} +.assembly GenDerive2{} + +.class public auto ansi beforefieldinit GenDerive2 extends class [GenDerive1]GenDerive1> { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.ilproj new file mode 100644 index 00000000000000..4c841ecd1683c2 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.il new file mode 100644 index 00000000000000..1d531f3f5db3ed --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.il @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly extern GenDerive2{} +.assembly GenDerive3{} + +.class public auto ansi beforefieldinit GenDerive3 extends class [GenDerive2]GenDerive2 { } + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.ilproj new file mode 100644 index 00000000000000..4463d91b5ac1bf --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.il new file mode 100644 index 00000000000000..094a68b83d0fdb --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.il @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly GenRetType{} + +.class public auto ansi beforefieldinit GenRetType { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.ilproj new file mode 100644 index 00000000000000..28124cdaf40f1b --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenTestType.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenTestType.il new file mode 100644 index 00000000000000..8b0e80812d4d9a --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenTestType.il @@ -0,0 +1,101 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} + +.assembly extern A { } +.assembly extern B { } +.assembly extern C { } +.assembly extern Dictionary { } +.assembly extern GenRetType { } +.assembly extern GenDerive1 { } +.assembly extern GenDerive2 { } +.assembly extern GenDerive3 { } +.assembly extern NonGenericDerived1 { } +.assembly extern NonGenericDerived2 { } +.assembly extern NonGenericDerived3 { } +.assembly extern NonGenericDerived4 { } +.assembly extern GenToNonGen1 { } +.assembly extern GenToNonGen2 { } +.assembly extern GenToNonGen3 { } +.assembly extern NonGenThroughGen1 { } +.assembly extern NonGenThroughGen2 { } +.assembly extern NonGenThroughGen3 { } +.assembly extern NonGenThroughGen4 { } + +.assembly extern GenBaseType { } + +.assembly GenTestType { } + +.class public auto ansi beforefieldinit GenTestType extends class [GenBaseType]GenBaseType +{ + .method public hidebysig newslot virtual instance class [NonGenThroughGen4]NonGenThroughGen4 NonGenThroughGenOverride(string& res) + { + .override method instance class [B]B class [GenBaseType]GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class [GenToNonGen3]GenToNonGen3 GenToNonGenOverride(string& res) + { + .override method instance class [B]B class [GenBaseType]GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class [NonGenericDerived4]NonGenericDerived4 NewGenFunc1(string& res) + { + .override method instance class [GenRetType]GenRetType class [GenBaseType]GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class [GenDerive3]GenDerive3 NewGenFunc2(string& res) + { + .override method instance class [GenRetType]GenRetType> class [GenBaseType]GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 TestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class [GenRetType]GenRetType NewFunc1(string& res) + { + .override method instance object class [GenBaseType]GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "GenRetType TestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class [C]C NewFunc2(string& res) + { + .override method instance class [B]B class [GenBaseType]GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "C TestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class [GenBaseType]GenBaseType::.ctor() + ret + } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenTestType.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenTestType.ilproj new file mode 100644 index 00000000000000..4d2eb180d699c8 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenTestType.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.il new file mode 100644 index 00000000000000..f86b57b3d47fba --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.il @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly extern C{} +.assembly GenToNonGen1{} + +.class public auto ansi beforefieldinit GenToNonGen1 extends [C]C { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.ilproj new file mode 100644 index 00000000000000..6431ad98866f61 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.il new file mode 100644 index 00000000000000..f8f34cb85b0ef1 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.il @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly extern GenToNonGen1{} +.assembly extern Dictionary{} +.assembly GenToNonGen2{} + +.class public auto ansi beforefieldinit GenToNonGen2 extends class [GenToNonGen1]GenToNonGen1> { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.ilproj new file mode 100644 index 00000000000000..4b942c58ba0aa8 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.il new file mode 100644 index 00000000000000..741ef9184c2cf2 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.il @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly extern GenToNonGen2 { } + +.assembly GenToNonGen3{} + + +.class public auto ansi beforefieldinit GenToNonGen3 extends class [GenToNonGen2]GenToNonGen2 { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.ilproj new file mode 100644 index 00000000000000..b8ad4600c9c6a1 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.il new file mode 100644 index 00000000000000..581a4275bb6eef --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.il @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern C{} +.assembly NonGenThroughGen1{} + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends [C]C { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.ilproj new file mode 100644 index 00000000000000..b15fc7a3cdb015 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.il new file mode 100644 index 00000000000000..1dd2d0410e47ef --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.il @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly extern NonGenThroughGen1{} +.assembly extern Dictionary{} +.assembly NonGenThroughGen2{} + +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class [NonGenThroughGen1]NonGenThroughGen1> { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.ilproj new file mode 100644 index 00000000000000..33147e73fb7c0f --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.il new file mode 100644 index 00000000000000..e55a296326bccb --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.il @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly extern NonGenThroughGen2{} +.assembly NonGenThroughGen3{} + +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class [NonGenThroughGen2]NonGenThroughGen2 { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.ilproj new file mode 100644 index 00000000000000..cc0e7773e557d3 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.il new file mode 100644 index 00000000000000..16a50342681806 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.il @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern NonGenThroughGen3{} +.assembly NonGenThroughGen4{} + +.class public auto ansi beforefieldinit NonGenThroughGen4 extends [NonGenThroughGen3]NonGenThroughGen3 { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.ilproj new file mode 100644 index 00000000000000..5a9a6a9848df56 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.il new file mode 100644 index 00000000000000..cc4f836083bb74 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.il @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern mscorlib { } +.assembly extern GenRetType { } + +.assembly NonGenericDerived1 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class [GenRetType]GenRetType { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.ilproj new file mode 100644 index 00000000000000..9f9d5761f55881 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.il new file mode 100644 index 00000000000000..50fd143311dd5b --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.il @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern mscorlib{} +.assembly extern NonGenericDerived1{} +.assembly NonGenericDerived2{} + +.class public auto ansi beforefieldinit NonGenericDerived2 extends class [NonGenericDerived1]NonGenericDerived1 { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.ilproj new file mode 100644 index 00000000000000..f6aaa70acbcc8a --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.il new file mode 100644 index 00000000000000..406a6a013bdfea --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.il @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern NonGenericDerived2{} +.assembly NonGenericDerived3{} + +.class public auto ansi beforefieldinit NonGenericDerived3 extends class [NonGenericDerived2]NonGenericDerived2 { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.ilproj new file mode 100644 index 00000000000000..d6f9c874cd545f --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.il new file mode 100644 index 00000000000000..8b803f0adf4cc7 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.il @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern NonGenericDerived3{} +.assembly NonGenericDerived4{} + +.class public auto ansi beforefieldinit NonGenericDerived4 extends [NonGenericDerived3]NonGenericDerived3 { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.ilproj new file mode 100644 index 00000000000000..fef53b39e4be4f --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.ilproj @@ -0,0 +1,11 @@ + + + + Library + BuildOnly + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il new file mode 100644 index 00000000000000..518534fbf7d0a6 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il @@ -0,0 +1,469 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly ReOverrideMoreDerivedReturn { } + +.class public auto ansi beforefieldinit A { } +.class public auto ansi beforefieldinit B extends A { } +.class public auto ansi beforefieldinit C extends B { } +.class public auto ansi beforefieldinit D extends C { } + +.class public auto ansi beforefieldinit GenRetType { } +.class public auto ansi beforefieldinit GenDerivedRetType extends class GenRetType { } +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.class public auto ansi beforefieldinit GenDerive4 extends class GenDerive3 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.class public auto ansi beforefieldinit NonGenericDerived5 extends NonGenericDerived4 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.class public auto ansi beforefieldinit GenToNonGen4 extends class GenToNonGen3 { } + + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.class public auto ansi beforefieldinit NonGenThroughGen5 extends NonGenThroughGen4 { } + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + + .method public hidebysig newslot virtual instance object MyFunc(string& res) + { + ldarg.0 + ldstr "object GenBaseType.MyFunc()" + stind.ref + newobj instance void A::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B MyFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.MyFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) + { + ldarg.0 + ldstr "B GenBaseType.GenToNonGen()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.NonGenThroughGenFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) + { + ldarg.0 + 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.0 + ldstr "GenRetType> GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType>::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) + { + ldarg.0 + ldstr "GenRetType GenBaseType.TestNonGenericDerived()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } +} + + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenTestType extends class GenBaseType +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 TestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerivedRetType NewFunc1(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "GenDerivedRetType TestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "C TestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenBaseType::.ctor() + ret + } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenDerivedTestType extends class GenTestType +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen5 NonGenThroughGenOverride(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen5 DerivedTestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen4 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen4 DerivedTestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived5 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived5 DerivedTestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive4 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive4 DerivedTestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerivedRetType NewFunc1(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "GenDerivedRetType DerivedTestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class D NewFunc2(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "D DerivedTestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static bool RunTest1() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenDerivedRetType DerivedTestType.NewFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance object class GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenDerivedRetType DerivedTestType.NewFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest2() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: D DerivedTestType.NewFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "D DerivedTestType.NewFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest3() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenDerive4 DerivedTestType.NewGenFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenDerive4 DerivedTestType.NewGenFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest4() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenericDerived5 DerivedTestType.NewGenFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenericDerived5 DerivedTestType.NewGenFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest5() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenToNonGen4 DerivedTestType.GenToNonGenOverride()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::GenToNonGen(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenToNonGen4 DerivedTestType.GenToNonGenOverride()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest6() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenThroughGen5 DerivedTestType.NonGenThroughGenFunc()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenThroughGen5 DerivedTestType.NonGenThroughGenFunc()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + T1: + call bool CMain::RunTest1() + brtrue.s T2 + ldc.i4.0 + stloc.0 + + T2: + call bool CMain::RunTest2() + brtrue.s T3 + ldc.i4.0 + stloc.0 + + T3: + call bool CMain::RunTest3() + brtrue.s T4 + ldc.i4.0 + stloc.0 + + T4: + call bool CMain::RunTest4() + brtrue.s T5 + ldc.i4.0 + stloc.0 + + T5: + call bool CMain::RunTest5() + brtrue.s T6 + ldc.i4.0 + stloc.0 + + T6: + call bool CMain::RunTest6() + brtrue.s DONE + ldc.i4.0 + 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 + } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.ilproj new file mode 100644 index 00000000000000..8617ffc5cdd29f --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il new file mode 100644 index 00000000000000..b0f7fc6c7c140c --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il @@ -0,0 +1,462 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly ReOverrideSameReturn { } + +.class public auto ansi beforefieldinit A { } +.class public auto ansi beforefieldinit B extends A { } +.class public auto ansi beforefieldinit C extends B { } + +.class public auto ansi beforefieldinit GenRetType { } +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + + .method public hidebysig newslot virtual instance object MyFunc(string& res) + { + ldarg.0 + ldstr "object GenBaseType.MyFunc()" + stind.ref + newobj instance void A::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B MyFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.MyFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) + { + ldarg.0 + ldstr "B GenBaseType.GenToNonGen()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.NonGenThroughGenFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) + { + ldarg.0 + 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.0 + ldstr "GenRetType> GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType>::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) + { + ldarg.0 + ldstr "GenRetType GenBaseType.TestNonGenericDerived()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } +} + + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenTestType extends class GenBaseType +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 TestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "GenRetType TestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "C TestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenBaseType::.ctor() + ret + } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenDerivedTestType extends class GenTestType +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 DerivedTestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen3 DerivedTestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 DerivedTestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 DerivedTestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "GenRetType DerivedTestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "C DerivedTestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static bool RunTest1() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenRetType DerivedTestType.NewFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance object class GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenRetType DerivedTestType.NewFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest2() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: C DerivedTestType.NewFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "C DerivedTestType.NewFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest3() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenDerive3 DerivedTestType.NewGenFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenDerive3 DerivedTestType.NewGenFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest4() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenericDerived4 DerivedTestType.NewGenFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenericDerived4 DerivedTestType.NewGenFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest5() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenToNonGen3 DerivedTestType.GenToNonGenOverride()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::GenToNonGen(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenToNonGen3 DerivedTestType.GenToNonGenOverride()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest6() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenThroughGen4 DerivedTestType.NonGenThroughGenFunc()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenThroughGen4 DerivedTestType.NonGenThroughGenFunc()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + T1: + call bool CMain::RunTest1() + brtrue.s T2 + ldc.i4.0 + stloc.0 + + T2: + call bool CMain::RunTest2() + brtrue.s T3 + ldc.i4.0 + stloc.0 + + T3: + call bool CMain::RunTest3() + brtrue.s T4 + ldc.i4.0 + stloc.0 + + T4: + call bool CMain::RunTest4() + brtrue.s T5 + ldc.i4.0 + stloc.0 + + T5: + call bool CMain::RunTest5() + brtrue.s T6 + ldc.i4.0 + stloc.0 + + T6: + call bool CMain::RunTest6() + brtrue.s DONE + ldc.i4.0 + 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 + } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.ilproj new file mode 100644 index 00000000000000..170f887ed88f0e --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il new file mode 100644 index 00000000000000..6bf44d18990117 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il @@ -0,0 +1,570 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Runtime { } +.assembly extern System.Private.CoreLib { } +.assembly extern mscorlib { } +.assembly UnitTest { } + +.class public auto ansi beforefieldinit A { } +.class public auto ansi beforefieldinit B extends A { } +.class public auto ansi beforefieldinit C extends B { } + +.class public auto ansi beforefieldinit GenRetType { } +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + + .method public hidebysig newslot virtual instance object MyFunc(string& res) + { + ldarg.0 + ldstr "object GenBaseType.MyFunc()" + stind.ref + newobj instance void A::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B MyFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.MyFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) + { + ldarg.0 + ldstr "B GenBaseType.GenToNonGen()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.NonGenThroughGenFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) + { + ldarg.0 + 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.0 + ldstr "GenRetType> GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType>::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) + { + ldarg.0 + ldstr "GenRetType GenBaseType.TestNonGenericDerived()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } +} + + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenMiddleType extends class GenBaseType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenBaseType::.ctor() + ret + } + + .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenOverride_Middle(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGenOverride_Middle(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen1> GenMiddleType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived1 NewGenFunc1_Middle(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived1 GenMiddleType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive1> NewGenFunc2_Middle(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive1> GenMiddleType.NewGenFunc2()" + stind.ref + ldnull + ret + } +} + + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenTestType extends class GenMiddleType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 TestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "GenRetType TestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "C TestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenMiddleType::.ctor() + ret + } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + // ============== Test using GenTestType ============== // + .method public static bool RunTest1() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenRetType TestType.NewFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance object class GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenRetType TestType.NewFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest2() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: C TestType.NewFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "C TestType.NewFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest3() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenDerive3 TestType.NewGenFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenDerive3 TestType.NewGenFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest4() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenericDerived4 TestType.NewGenFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest5() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenToNonGen3 TestType.GenToNonGenOverride()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::GenToNonGen(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest6() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + // ============== Test using GenMiddleType ============== // + .method public static bool RunTest_Middle1() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenDerive1> GenMiddleType.NewGenFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenDerive1> GenMiddleType.NewGenFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest_Middle2() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenericDerived1 GenMiddleType.NewGenFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenericDerived1 GenMiddleType.NewGenFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest_Middle3() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenToNonGen1> GenMiddleType.GenToNonGenOverride()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::GenToNonGen(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenToNonGen1> GenMiddleType.GenToNonGenOverride()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest_Middle4() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + // ===================================================================================== // + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + T1: + call bool CMain::RunTest1() + brtrue.s T2 + ldc.i4.0 + stloc.0 + + T2: + call bool CMain::RunTest2() + brtrue.s T3 + ldc.i4.0 + stloc.0 + + T3: + call bool CMain::RunTest3() + brtrue.s T4 + ldc.i4.0 + stloc.0 + + T4: + call bool CMain::RunTest4() + brtrue.s T5 + ldc.i4.0 + stloc.0 + + T5: + call bool CMain::RunTest5() + brtrue.s T6 + ldc.i4.0 + stloc.0 + + T6: + call bool CMain::RunTest6() + brtrue.s M1 + ldc.i4.0 + stloc.0 + + M1: + call bool CMain::RunTest_Middle1() + brtrue.s M2 + ldc.i4.0 + stloc.0 + + M2: + call bool CMain::RunTest_Middle2() + brtrue.s M3 + ldc.i4.0 + stloc.0 + + M3: + call bool CMain::RunTest_Middle3() + brtrue.s M4 + ldc.i4.0 + stloc.0 + + M4: + call bool CMain::RunTest_Middle4() + brtrue.s DONE + ldc.i4.0 + 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 + } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.ilproj new file mode 100644 index 00000000000000..921b93a2356ead --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il new file mode 100644 index 00000000000000..57386432306adc --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il @@ -0,0 +1,425 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly UnitTestDelegates { } + +.class public auto ansi beforefieldinit A { } +.class public auto ansi beforefieldinit B extends A { } +.class public auto ansi beforefieldinit C extends B { } + +.class public auto ansi beforefieldinit GenRetType { } +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + + .method public hidebysig newslot virtual instance object MyFunc(string& res) + { + ldarg.0 + ldstr "object GenBaseType.MyFunc()" + stind.ref + newobj instance void A::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B MyFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.MyFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) + { + ldarg.0 + ldstr "B GenBaseType.GenToNonGen()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.NonGenThroughGenFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) + { + ldarg.0 + 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.0 + ldstr "GenRetType> GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType>::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) + { + ldarg.0 + ldstr "GenRetType GenBaseType.TestNonGenericDerived()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } +} + + + +.class public auto ansi beforefieldinit GenTestType extends class GenBaseType +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 TestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "GenRetType TestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "C TestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenBaseType::.ctor() + ret + } +} + + + + +.class public auto ansi sealed ReturnObjDel extends [System.Runtime]System.MulticastDelegate +{ + // We can use a delegate with signature 'object Invoke(string&)' for all methods here since they all return a reference type + + .method public hidebysig specialname rtspecialname instance void .ctor (object 'object', native int 'method') runtime managed { } + .method public hidebysig newslot virtual instance class [System.Runtime]System.IAsyncResult BeginInvoke (string& res, class [System.Runtime]System.AsyncCallback callback, object 'object') runtime managed { } + .method public hidebysig newslot virtual instance object Invoke (string& res) runtime managed { } + .method public hidebysig newslot virtual instance object EndInvoke (string& res, class [System.Runtime]System.IAsyncResult result) runtime managed { } +} + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static bool RunTest1() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenRetType TestType.NewFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + dup + ldvirtftn instance object class GenBaseType::MyFunc(string&) + newobj instance void class ReturnObjDel::.ctor(object, native int) + + ldloca.s 0 + callvirt instance object class ReturnObjDel::Invoke(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenRetType TestType.NewFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest2() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: C TestType.NewFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + dup + ldvirtftn instance class B class GenBaseType::MyFunc(string&) + newobj instance void class ReturnObjDel::.ctor(object, native int) + + ldloca.s 0 + callvirt instance object class ReturnObjDel::Invoke(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "C TestType.NewFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest3() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenDerive3 TestType.NewGenFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + dup + ldvirtftn instance class GenRetType> class GenBaseType::MyGenFunc(string&) + newobj instance void class ReturnObjDel::.ctor(object, native int) + + ldloca.s 0 + callvirt instance object class ReturnObjDel::Invoke(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenDerive3 TestType.NewGenFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest4() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenericDerived4 TestType.NewGenFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + dup + ldvirtftn instance class GenRetType class GenBaseType::MyGenFunc(string&) + newobj instance void class ReturnObjDel::.ctor(object, native int) + + ldloca.s 0 + callvirt instance object class ReturnObjDel::Invoke(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest5() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenToNonGen3 TestType.GenToNonGenOverride()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + dup + ldvirtftn instance class B class GenBaseType::GenToNonGen(string&) + newobj instance void class ReturnObjDel::.ctor(object, native int) + + ldloca.s 0 + callvirt instance object class ReturnObjDel::Invoke(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest6() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + dup + ldvirtftn instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + newobj instance void class ReturnObjDel::.ctor(object, native int) + + ldloca.s 0 + callvirt instance object class ReturnObjDel::Invoke(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + T1: + call bool CMain::RunTest1() + brtrue.s T2 + ldc.i4.0 + stloc.0 + + T2: + call bool CMain::RunTest2() + brtrue.s T3 + ldc.i4.0 + stloc.0 + + T3: + call bool CMain::RunTest3() + brtrue.s T4 + ldc.i4.0 + stloc.0 + + T4: + call bool CMain::RunTest4() + brtrue.s T5 + ldc.i4.0 + stloc.0 + + T5: + call bool CMain::RunTest5() + brtrue.s T6 + ldc.i4.0 + stloc.0 + + T6: + call bool CMain::RunTest6() + brtrue.s DONE + ldc.i4.0 + 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 + } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj new file mode 100644 index 00000000000000..1667d3b14ac0ba --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestMultiModule.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestMultiModule.il new file mode 100644 index 00000000000000..3a0b2f40158488 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestMultiModule.il @@ -0,0 +1,245 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } + +.assembly extern A { } +.assembly extern B { } +.assembly extern C { } +.assembly extern Dictionary { } +.assembly extern GenRetType { } +.assembly extern GenDerive1 { } +.assembly extern GenDerive2 { } +.assembly extern GenDerive3 { } +.assembly extern NonGenericDerived1 { } +.assembly extern NonGenericDerived2 { } +.assembly extern NonGenericDerived3 { } +.assembly extern NonGenericDerived4 { } +.assembly extern GenToNonGen1 { } +.assembly extern GenToNonGen2 { } +.assembly extern GenToNonGen3 { } +.assembly extern NonGenThroughGen1 { } +.assembly extern NonGenThroughGen2 { } +.assembly extern NonGenThroughGen3 { } +.assembly extern NonGenThroughGen4 { } + +.assembly extern GenBaseType { } +.assembly extern GenTestType { } + +.assembly UnitTestMultiModule { } + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static bool RunTest1() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenRetType TestType.NewFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class [GenTestType]GenTestType::.ctor() + ldloca.s 0 + callvirt instance object class [GenBaseType]GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenRetType TestType.NewFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest2() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: C TestType.NewFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class [GenTestType]GenTestType::.ctor() + ldloca.s 0 + callvirt instance class [B]B class [GenBaseType]GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "C TestType.NewFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest3() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenDerive3 TestType.NewGenFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class [GenTestType]GenTestType::.ctor() + ldloca.s 0 + callvirt instance class [GenRetType]GenRetType> class [GenBaseType]GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenDerive3 TestType.NewGenFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest4() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenericDerived4 TestType.NewGenFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class [GenTestType]GenTestType::.ctor() + ldloca.s 0 + callvirt instance class [GenRetType]GenRetType class [GenBaseType]GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest5() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenToNonGen3 TestType.GenToNonGenOverride()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class [GenTestType]GenTestType::.ctor() + ldloca.s 0 + callvirt instance class [B]B class [GenBaseType]GenBaseType::GenToNonGen(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest6() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class [GenTestType]GenTestType::.ctor() + ldloca.s 0 + callvirt instance class [B]B class [GenBaseType]GenBaseType::NonGenThroughGenFunc(string& res) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + T1: + call bool CMain::RunTest1() + brtrue.s T2 + ldc.i4.0 + stloc.0 + + T2: + call bool CMain::RunTest2() + brtrue.s T3 + ldc.i4.0 + stloc.0 + + T3: + call bool CMain::RunTest3() + brtrue.s T4 + ldc.i4.0 + stloc.0 + + T4: + call bool CMain::RunTest4() + brtrue.s T5 + ldc.i4.0 + stloc.0 + + T5: + call bool CMain::RunTest5() + brtrue.s T6 + ldc.i4.0 + stloc.0 + + T6: + call bool CMain::RunTest6() + brtrue.s DONE + ldc.i4.0 + 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 + } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestMultiModule.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestMultiModule.ilproj new file mode 100644 index 00000000000000..f745a3e04ee199 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestMultiModule.ilproj @@ -0,0 +1,35 @@ + + + Exe + BuildAndRun + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il new file mode 100644 index 00000000000000..e21b9b5217e5be --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il @@ -0,0 +1,723 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Runtime { } +.assembly extern System.Private.CoreLib { } +.assembly extern mscorlib { } +.assembly UnitTest_GVM { } + +.class public auto ansi beforefieldinit A { } +.class public auto ansi beforefieldinit B extends A { } +.class public auto ansi beforefieldinit C extends B { } + +.class public auto ansi beforefieldinit GenRetType { } +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.class public auto ansi beforefieldinit NonGenericDerived5 extends class NonGenericDerived1 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.class public auto ansi beforefieldinit NonGenThroughGen5 extends class NonGenThroughGen2 { } + + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + + .method public hidebysig newslot virtual instance object MyFunc(string& res) + { + ldarg.0 + ldstr "object GenBaseType.MyFunc()" + stind.ref + newobj instance void A::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B MyFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.MyFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) + { + ldarg.0 + ldstr "B GenBaseType.GenToNonGen()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.NonGenThroughGenFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) + { + ldarg.0 + 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.0 + ldstr "GenRetType> GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType>::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) + { + ldarg.0 + ldstr "GenRetType GenBaseType.TestNonGenericDerived()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } +} + + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenMiddleType extends class GenBaseType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenBaseType::.ctor() + ret + } + + .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenOverride_Middle(string& res) + { + .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> GenToNonGenOverride_Middle(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) + ldarg.1 + ldstr "GenToNonGen1> GenMiddleType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived1 NewGenFunc1_Middle(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) + ldarg.1 + ldstr "NonGenericDerived1 GenMiddleType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive2 NewGenFunc2_Middle(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) + ldarg.1 + ldstr "GenDerive2 GenMiddleType.NewGenFunc2()" + stind.ref + ldnull + ret + } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenTestType extends class GenMiddleType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig newslot virtual instance class NonGenThroughGen5 NonGenThroughGenOverride(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 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived5 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) + ldarg.1 + ldstr "NonGenericDerived5 TestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive2 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) + ldarg.1 + ldstr "GenDerive2 TestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) + { + .override method instance object class GenBaseType::MyFunc<[1]>(string& res) + ldarg.1 + ldstr "GenRetType TestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + { + .override method instance class B class GenBaseType::MyFunc<[1]>(string& res) + ldarg.1 + ldstr "C TestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenMiddleType::.ctor() + ret + } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit Invalid1 extends class GenMiddleType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + // 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 + } +} +.class public auto ansi beforefieldinit Invalid2 extends class GenMiddleType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + // 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 + } +} +.class public auto ansi beforefieldinit Invalid3 extends class GenMiddleType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + // 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 + } +} +.class public auto ansi beforefieldinit Invalid4 extends class GenMiddleType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + // 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 + } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + // ============== Test using GenTestType ============== // + .method public static bool RunTest1() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenRetType TestType.NewFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance object class GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenRetType TestType.NewFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest2() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: C TestType.NewFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "C TestType.NewFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest3() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenDerive2 TestType.NewGenFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenDerive2 TestType.NewGenFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest4() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenericDerived5 TestType.NewGenFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenericDerived5 TestType.NewGenFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest5() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenToNonGen3 TestType.GenToNonGenOverride()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::GenToNonGen(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest6() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenThroughGen5 TestType.NonGenThroughGenFunc()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenThroughGen5 TestType.NonGenThroughGenFunc()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + // ============== Test using GenMiddleType ============== // + .method public static bool RunTest_Middle1() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenDerive2 GenMiddleType.NewGenFunc2()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenDerive2 GenMiddleType.NewGenFunc2()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest_Middle2() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenericDerived1 GenMiddleType.NewGenFunc1()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenericDerived1 GenMiddleType.NewGenFunc1()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest_Middle3() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: GenToNonGen1> GenMiddleType.GenToNonGenOverride()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::GenToNonGen(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "GenToNonGen1> GenMiddleType.GenToNonGenOverride()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest_Middle4() noinlining + { + .locals init (string res, bool flag) + + ldstr "EXPECTED: NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + // ===================================================================================== // + .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( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + T1: + call bool CMain::RunTest1() + brtrue.s T2 + ldc.i4.0 + stloc.0 + + T2: + call bool CMain::RunTest2() + brtrue.s T3 + ldc.i4.0 + stloc.0 + + T3: + call bool CMain::RunTest3() + brtrue.s T4 + ldc.i4.0 + stloc.0 + + T4: + call bool CMain::RunTest4() + brtrue.s T5 + ldc.i4.0 + stloc.0 + + T5: + call bool CMain::RunTest5() + brtrue.s T6 + ldc.i4.0 + stloc.0 + + T6: + call bool CMain::RunTest6() + brtrue.s M1 + ldc.i4.0 + stloc.0 + + M1: + call bool CMain::RunTest_Middle1() + brtrue.s M2 + ldc.i4.0 + stloc.0 + + M2: + call bool CMain::RunTest_Middle2() + brtrue.s M3 + ldc.i4.0 + stloc.0 + + M3: + call bool CMain::RunTest_Middle3() + brtrue.s M4 + ldc.i4.0 + stloc.0 + + M4: + call bool CMain::RunTest_Middle4() + brtrue.s INVALID1 + 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 + + 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/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.ilproj new file mode 100644 index 00000000000000..6dbb26234d34e0 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il new file mode 100644 index 00000000000000..f4a776cd1e87a8 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il @@ -0,0 +1,366 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Private.CoreLib { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly IncompatibleReturnNoValidation { } + +.class public auto ansi beforefieldinit A { } +.class public auto ansi beforefieldinit B extends A { } +.class public auto ansi beforefieldinit C extends B { } + +.class public auto ansi beforefieldinit GenRetType { } +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + + .method public hidebysig newslot virtual instance object MyFunc(string& res) + { + ldarg.0 + ldstr "object GenBaseType.MyFunc()" + stind.ref + newobj instance void A::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B MyFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.MyFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) + { + ldarg.0 + ldstr "B GenBaseType.GenToNonGen()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.NonGenThroughGenFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) + { + ldarg.0 + 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.0 + ldstr "GenRetType> GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType>::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) + { + ldarg.0 + ldstr "GenRetType GenBaseType.TestNonGenericDerived()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } +} + + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenTestType extends class GenBaseType +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 TestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "GenRetType TestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "C TestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenBaseType::.ctor() + ret + } +} + +// ======================================================================================== + +// ======================================================================================== +// The following types are overriding base type methods that have already been overridden +// with covariant return types, but the return type here is not compatible (return type is +// a base type of the covariant return type of existing overrides). Validation is only +// triggered by the presense of the ValidateMethodImplRemainsInEffect attribute, so the +// following types should successfully load since they do not have the attribute. +// ======================================================================================== +.class public auto ansi beforefieldinit IncompatibleButValid1 extends class GenTestType +{ + .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride_IncompatibleButValid(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit IncompatibleButValid2 extends class GenTestType +{ + .method public hidebysig newslot virtual instance class B GenToNonGenOverride_IncompatibleButValid(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit IncompatibleButValid3 extends class GenTestType +{ + .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1_IncompatibleButValid(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit IncompatibleButValid4 extends class GenTestType +{ + .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2_IncompatibleButValid(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit IncompatibleButValid5 extends class GenTestType +{ + .method public hidebysig newslot virtual instance object NewFunc1_IncompatibleButValid(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit IncompatibleButValid6 extends class GenTestType +{ + .method public hidebysig newslot virtual instance class B NewFunc2_IncompatibleButValid(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + newobj instance void class IncompatibleButValid1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + newobj instance void class IncompatibleButValid2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + newobj instance void class IncompatibleButValid3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + newobj instance void class IncompatibleButValid4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + newobj instance void class IncompatibleButValid5::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest6() noinlining + { + newobj instance void class IncompatibleButValid6::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + + // No exception should be thrown here. + call void CMain::RunTest1() + call void CMain::RunTest2() + call void CMain::RunTest3() + call void CMain::RunTest4() + call void CMain::RunTest5() + call void CMain::RunTest6() + + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + 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/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.ilproj new file mode 100644 index 00000000000000..01553924a15bbe --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il new file mode 100644 index 00000000000000..060388477f844b --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il @@ -0,0 +1,483 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Private.CoreLib { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly OverrideSameSigAsDecl { } + +.class public auto ansi beforefieldinit A { } +.class public auto ansi beforefieldinit B extends A { } +.class public auto ansi beforefieldinit C extends B { } + +.class public auto ansi beforefieldinit GenRetType { } +.class public auto ansi beforefieldinit Dictionary { } + +.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } +.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } + +.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } + +.class public auto ansi beforefieldinit GenToNonGen1 extends C { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } + + +.class public auto ansi beforefieldinit NonGenThroughGen1 extends C { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + + .method public hidebysig newslot virtual instance object MyFunc(string& res) + { + ldarg.0 + ldstr "object GenBaseType.MyFunc()" + stind.ref + newobj instance void A::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B MyFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.MyFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) + { + ldarg.0 + ldstr "B GenBaseType.GenToNonGen()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) + { + ldarg.0 + ldstr "B GenBaseType.NonGenThroughGenFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) + { + ldarg.0 + 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.0 + ldstr "GenRetType> GenBaseType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType>::.ctor() + ret + } + .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) + { + ldarg.0 + ldstr "GenRetType GenBaseType.TestNonGenericDerived()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } +} + + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenTestType extends class GenBaseType +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 TestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "GenRetType TestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "C TestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenBaseType::.ctor() + ret + } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit Invalid1 extends class GenTestType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride_Invalid(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit Invalid2 extends class GenTestType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig newslot virtual instance class B GenToNonGenOverride_Invalid(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit Invalid3 extends class GenTestType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1_Invalid(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit Invalid4 extends class GenTestType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2_Invalid(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit Invalid5 extends class GenTestType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig newslot virtual instance object NewFunc1_Invalid(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit Invalid6 extends class GenTestType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig newslot virtual instance class B NewFunc2_Invalid(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenTestType::.ctor() + ret + } +} + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + newobj instance void class Invalid1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + newobj instance void class Invalid2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + newobj instance void class Invalid3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + newobj instance void class Invalid4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + newobj instance void class Invalid5::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest6() noinlining + { + newobj instance void class Invalid6::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + 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 T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + 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 T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + 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 T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + 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 T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid5." + call void [System.Console]System.Console::WriteLine(string) + leave.s T6 + } + 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 T6 + } + + T6: + .try + { + call void CMain::RunTest6() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid6." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + 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/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.ilproj new file mode 100644 index 00000000000000..7832fd86e93975 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 8fe6a6dca457c8..095e1281bf3b06 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -649,6 +649,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs new file mode 100644 index 00000000000000..2da77ceb45fe9f --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] + public sealed class ValidateMethodImplRemainsInEffectAttribute : Attribute + { + } +} From fef49b2b3d1a9907e656cbd0d4e519dc86373362 Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Wed, 22 Apr 2020 14:29:52 -0700 Subject: [PATCH 02/21] Adding the missing .ctor methods to the various types --- .../InterfaceReturns/InterfaceReturns.il | 82 ++++++++-- .../InterfaceReturns/InterfaceReturns2.il | 66 ++++++-- .../InterfaceReturns/InterfaceReturns3.il | 81 +++++++--- .../InterfaceReturns/InterfaceReturns4.il | 76 ++++++--- .../StructReturns/StructReturns.il | 91 +++++++++-- .../StructReturns/StructReturns2.il | 91 +++++++++-- .../CovariantReturns/UnitTest/Modules/A.il | 6 +- .../CovariantReturns/UnitTest/Modules/B.il | 6 +- .../CovariantReturns/UnitTest/Modules/C.il | 6 +- .../UnitTest/Modules/Dictionary.il | 6 +- .../UnitTest/Modules/GenBaseType.il | 14 +- .../UnitTest/Modules/GenDerive1.il | 5 +- .../UnitTest/Modules/GenDerive2.il | 5 +- .../UnitTest/Modules/GenDerive3.il | 6 +- .../UnitTest/Modules/GenRetType.il | 5 +- .../UnitTest/Modules/GenToNonGen1.il | 5 +- .../UnitTest/Modules/GenToNonGen2.il | 5 +- .../UnitTest/Modules/GenToNonGen3.il | 6 +- .../UnitTest/Modules/NonGenThroughGen1.il | 4 +- .../UnitTest/Modules/NonGenThroughGen2.il | 4 +- .../UnitTest/Modules/NonGenThroughGen3.il | 7 +- .../UnitTest/Modules/NonGenThroughGen4.il | 6 +- .../UnitTest/Modules/NonGenericDerived1.il | 4 +- .../UnitTest/Modules/NonGenericDerived2.il | 5 +- .../UnitTest/Modules/NonGenericDerived3.il | 4 +- .../UnitTest/Modules/NonGenericDerived4.il | 4 +- .../UnitTest/OverrideMoreDerivedReturn.il | 151 +++++++++++++----- .../UnitTest/OverrideSameReturn.il | 109 ++++++++++--- .../CovariantReturns/UnitTest/UnitTest.il | 109 ++++++++++--- .../UnitTest/UnitTestDelegates.il | 109 ++++++++++--- .../CovariantReturns/UnitTest/UnitTest_GVM.il | 119 ++++++++++---- .../IncompatibleReturnNoValidation.il | 109 ++++++++++--- .../Validation/OverrideSameSigAsDecl.il | 90 ++++++++--- 33 files changed, 1070 insertions(+), 326 deletions(-) diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il index 5328d287bd74ad..52039831dbb941 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il @@ -11,25 +11,70 @@ .class interface public auto ansi abstract IC implements IB { } .class interface public auto ansi abstract IGenRetType { } -.class public auto ansi beforefieldinit Dictionary { } +.class public auto ansi beforefieldinit Dictionary +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} -.class public auto ansi beforefieldinit GenDerive1 implements class IGenRetType { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.class public auto ansi beforefieldinit GenDerive1 implements class IGenRetType +{ + .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 implements class IGenRetType { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.class public auto ansi beforefieldinit NonGenericDerived1 implements class IGenRetType +{ + .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 GenToNonGen1 implements IC { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.class public auto ansi beforefieldinit GenToNonGen1 implements IC +{ + .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 implements class IC { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.class public auto ansi beforefieldinit NonGenThroughGen1 implements class IC +{ + .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 BaseTest { @@ -63,6 +108,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test1 extends class BaseTest @@ -73,6 +119,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test2 extends class BaseTest @@ -83,6 +130,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test3 extends class BaseTest @@ -93,6 +141,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test4 extends class BaseTest @@ -103,6 +152,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test5 extends class BaseTest @@ -113,6 +163,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test6 extends class BaseTest @@ -123,6 +174,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il index df136fbada4524..0871befbc6de7f 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il @@ -11,25 +11,55 @@ .class interface public auto ansi abstract IC implements IB { } .class interface public auto ansi abstract IGenRetType { } -.class public auto ansi beforefieldinit Dictionary { } +.class public auto ansi beforefieldinit Dictionary { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} -.class public auto ansi beforefieldinit GenDerive1 implements class IGenRetType { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.class public auto ansi beforefieldinit GenDerive1 implements class IGenRetType { + .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 implements class IGenRetType { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.class public auto ansi beforefieldinit NonGenericDerived1 implements class IGenRetType { + .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 GenToNonGen1 implements IC { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.class public auto ansi beforefieldinit GenToNonGen1 implements IC { + .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 implements class IC { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.class public auto ansi beforefieldinit NonGenThroughGen1 implements class IC { + .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 BaseTest { @@ -58,6 +88,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test1 extends class BaseTest @@ -68,6 +99,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test2 extends class BaseTest @@ -78,6 +110,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test3 extends class BaseTest @@ -88,6 +121,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test4 extends class BaseTest @@ -98,6 +132,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test5 extends class BaseTest @@ -108,6 +143,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il index d92fa42a24f6b8..870596fbcd1016 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il @@ -6,31 +6,69 @@ .assembly extern mscorlib { } .assembly InterfaceReturns { } -.class public auto ansi beforefieldinit A { } -.class public auto ansi beforefieldinit B extends A { } -.class public auto ansi beforefieldinit C extends B { } +.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 { } +.class public auto ansi beforefieldinit GenRetType { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} -.class public auto ansi beforefieldinit Dictionary { } +.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 { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.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 GenToNonGen1 extends C { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.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 class C { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.class public auto ansi beforefieldinit NonGenThroughGen1 extends class 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 interface public auto ansi abstract BaseTest { @@ -69,6 +107,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test2 implements class BaseTest @@ -79,6 +118,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test3 implements class BaseTest @@ -89,6 +129,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test4 implements class BaseTest @@ -99,6 +140,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test5 implements class BaseTest @@ -109,6 +151,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il index ca5824ea824226..1b3ab0a5e0457e 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il @@ -6,31 +6,69 @@ .assembly extern mscorlib { } .assembly InterfaceReturns { } -.class public auto ansi beforefieldinit A { } -.class public auto ansi beforefieldinit B extends A { } -.class public auto ansi beforefieldinit C extends B { } +.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 { } +.class public auto ansi beforefieldinit GenRetType { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} -.class public auto ansi beforefieldinit Dictionary { } +.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 { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.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 GenToNonGen1 extends C { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.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 class C { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.class public auto ansi beforefieldinit NonGenThroughGen1 extends class 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 interface public auto ansi abstract BaseTest { diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il index e0da29eccb9f01..744dd316b2a8fb 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il @@ -10,27 +10,78 @@ .class public sealed auto ansi GenStruct extends [mscorlib]System.ValueType { } -.class public auto ansi C { } -.class public auto ansi GenRetType { } -.class public auto ansi beforefieldinit Dictionary { } +.class public auto ansi C +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi 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 { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.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 GenToNonGen1 extends C { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.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 class C { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.class public auto ansi beforefieldinit NonGenThroughGen1 extends class 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 BaseType @@ -60,6 +111,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test1 extends class BaseType @@ -70,6 +122,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test2 extends class BaseType @@ -80,6 +133,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test3 extends class BaseType @@ -90,6 +144,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test4 extends class BaseType @@ -100,6 +155,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test5 extends class BaseType @@ -110,6 +166,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il index a36b91e8a2b00f..d403cb1a33af9b 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il @@ -10,27 +10,78 @@ .class public sealed auto ansi GenStruct extends [mscorlib]System.ValueType { } -.class public auto ansi C { } -.class public auto ansi GenRetType { } -.class public auto ansi beforefieldinit Dictionary { } +.class public auto ansi C +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} +.class public auto ansi 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 { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.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 GenToNonGen1 extends C { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.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 class C { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.class public auto ansi beforefieldinit NonGenThroughGen1 extends class 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 BaseType @@ -60,6 +111,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test1 extends class BaseType @@ -70,6 +122,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test2 extends class BaseType @@ -80,6 +133,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test3 extends class BaseType @@ -90,6 +144,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test4 extends class BaseType @@ -100,6 +155,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Test5 extends class BaseType @@ -110,6 +166,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.il index 0388370550bc28..78bc586b531020 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/A.il @@ -6,4 +6,8 @@ .assembly extern mscorlib{} .assembly A{} -.class public auto ansi beforefieldinit A { } +.class public auto ansi beforefieldinit A +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.il index 3a49d6fd3f9644..92f988163e670f 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/B.il @@ -7,4 +7,8 @@ .assembly B{} -.class public auto ansi beforefieldinit B extends [A]A { } +.class public auto ansi beforefieldinit B extends [A]A +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.il index ece5321703e258..a151cd015efd8c 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/C.il @@ -7,4 +7,8 @@ .assembly extern B{} .assembly C{} -.class public auto ansi beforefieldinit C extends [B]B { } +.class public auto ansi beforefieldinit C extends [B]B +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.il index f23cc2e3f2e7f7..dec049b045bbad 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/Dictionary.il @@ -6,4 +6,8 @@ .assembly extern mscorlib{} .assembly Dictionary{} -.class public auto ansi beforefieldinit Dictionary { } +.class public auto ansi beforefieldinit Dictionary +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.il index 7d70bf4fb86135..3b79f7a200772f 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenBaseType.il @@ -23,7 +23,7 @@ .method public hidebysig newslot virtual instance object MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "object GenBaseType.MyFunc()" stind.ref newobj instance void [A]A::.ctor() @@ -31,7 +31,7 @@ } .method public hidebysig newslot virtual instance class [B]B MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.MyFunc()" stind.ref newobj instance void [B]B::.ctor() @@ -39,7 +39,7 @@ } .method public hidebysig newslot virtual instance class [B]B GenToNonGen(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.GenToNonGen()" stind.ref newobj instance void [B]B::.ctor() @@ -47,7 +47,7 @@ } .method public hidebysig newslot virtual instance class [B]B NonGenThroughGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.NonGenThroughGenFunc()" stind.ref newobj instance void [B]B::.ctor() @@ -55,7 +55,7 @@ } .method public hidebysig newslot virtual instance class [GenRetType]GenRetType MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.MyGenFunc()" stind.ref newobj instance void class [GenRetType]GenRetType::.ctor() @@ -63,7 +63,7 @@ } .method public hidebysig newslot virtual instance class [GenRetType]GenRetType> MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType> GenBaseType.MyGenFunc()" stind.ref newobj instance void class [GenRetType]GenRetType>::.ctor() @@ -71,7 +71,7 @@ } .method public hidebysig newslot virtual instance class [GenRetType]GenRetType TestNonGenericDerived(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.TestNonGenericDerived()" stind.ref newobj instance void class [GenRetType]GenRetType::.ctor() diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.il index 9678d6dda30015..7ba3ff8507c8b9 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive1.il @@ -7,4 +7,7 @@ .assembly extern GenRetType{} .assembly GenDerive1{} -.class public auto ansi beforefieldinit GenDerive1 extends class [GenRetType]GenRetType { } +.class public auto ansi beforefieldinit GenDerive1 extends class [GenRetType]GenRetType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.il index b50fbfc783ea66..2a2d9b8da7c08f 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive2.il @@ -8,4 +8,7 @@ .assembly extern Dictionary{} .assembly GenDerive2{} -.class public auto ansi beforefieldinit GenDerive2 extends class [GenDerive1]GenDerive1> { } +.class public auto ansi beforefieldinit GenDerive2 extends class [GenDerive1]GenDerive1> +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.il index 1d531f3f5db3ed..0be33cd740c20c 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenDerive3.il @@ -7,5 +7,7 @@ .assembly extern GenDerive2{} .assembly GenDerive3{} -.class public auto ansi beforefieldinit GenDerive3 extends class [GenDerive2]GenDerive2 { } - +.class public auto ansi beforefieldinit GenDerive3 extends class [GenDerive2]GenDerive2 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.il index 094a68b83d0fdb..f36dcc47430eaf 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenRetType.il @@ -6,4 +6,7 @@ .assembly extern mscorlib{} .assembly GenRetType{} -.class public auto ansi beforefieldinit GenRetType { } +.class public auto ansi beforefieldinit GenRetType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.il index f86b57b3d47fba..0db5ede06079dd 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen1.il @@ -7,4 +7,7 @@ .assembly extern C{} .assembly GenToNonGen1{} -.class public auto ansi beforefieldinit GenToNonGen1 extends [C]C { } +.class public auto ansi beforefieldinit GenToNonGen1 extends [C]C +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.il index f8f34cb85b0ef1..9556f0ed989519 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen2.il @@ -8,4 +8,7 @@ .assembly extern Dictionary{} .assembly GenToNonGen2{} -.class public auto ansi beforefieldinit GenToNonGen2 extends class [GenToNonGen1]GenToNonGen1> { } +.class public auto ansi beforefieldinit GenToNonGen2 extends class [GenToNonGen1]GenToNonGen1> +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.il index 741ef9184c2cf2..bcbd4eb12851e6 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/GenToNonGen3.il @@ -8,5 +8,7 @@ .assembly GenToNonGen3{} - -.class public auto ansi beforefieldinit GenToNonGen3 extends class [GenToNonGen2]GenToNonGen2 { } +.class public auto ansi beforefieldinit GenToNonGen3 extends class [GenToNonGen2]GenToNonGen2 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.il index 581a4275bb6eef..e47082ab030f69 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen1.il @@ -6,4 +6,6 @@ .assembly extern C{} .assembly NonGenThroughGen1{} -.class public auto ansi beforefieldinit NonGenThroughGen1 extends [C]C { } +.class public auto ansi beforefieldinit NonGenThroughGen1 extends [C]C { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.il index 1dd2d0410e47ef..beab86bb6d8962 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen2.il @@ -8,4 +8,6 @@ .assembly extern Dictionary{} .assembly NonGenThroughGen2{} -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class [NonGenThroughGen1]NonGenThroughGen1> { } +.class public auto ansi beforefieldinit NonGenThroughGen2 extends class [NonGenThroughGen1]NonGenThroughGen1> { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.il index e55a296326bccb..e0e83f9a419343 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen3.il @@ -7,4 +7,9 @@ .assembly extern NonGenThroughGen2{} .assembly NonGenThroughGen3{} -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class [NonGenThroughGen2]NonGenThroughGen2 { } +.class public auto ansi beforefieldinit NonGenThroughGen3 extends class [NonGenThroughGen2]NonGenThroughGen2 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.il index 16a50342681806..2e2401783c9c88 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenThroughGen4.il @@ -6,4 +6,8 @@ .assembly extern NonGenThroughGen3{} .assembly NonGenThroughGen4{} -.class public auto ansi beforefieldinit NonGenThroughGen4 extends [NonGenThroughGen3]NonGenThroughGen3 { } +.class public auto ansi beforefieldinit NonGenThroughGen4 extends [NonGenThroughGen3]NonGenThroughGen3 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.il index cc4f836083bb74..07b26bf22890d3 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived1.il @@ -7,4 +7,6 @@ .assembly NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived1 extends class [GenRetType]GenRetType { } +.class public auto ansi beforefieldinit NonGenericDerived1 extends class [GenRetType]GenRetType { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.il index 50fd143311dd5b..4cc4f7e3530b87 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived2.il @@ -7,4 +7,7 @@ .assembly extern NonGenericDerived1{} .assembly NonGenericDerived2{} -.class public auto ansi beforefieldinit NonGenericDerived2 extends class [NonGenericDerived1]NonGenericDerived1 { } +.class public auto ansi beforefieldinit NonGenericDerived2 extends class [NonGenericDerived1]NonGenericDerived1 { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.il index 406a6a013bdfea..08face4ff92089 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived3.il @@ -6,4 +6,6 @@ .assembly extern NonGenericDerived2{} .assembly NonGenericDerived3{} -.class public auto ansi beforefieldinit NonGenericDerived3 extends class [NonGenericDerived2]NonGenericDerived2 { } +.class public auto ansi beforefieldinit NonGenericDerived3 extends class [NonGenericDerived2]NonGenericDerived2 { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.il index 8b803f0adf4cc7..7e761a1b021de3 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/Modules/NonGenericDerived4.il @@ -6,4 +6,6 @@ .assembly extern NonGenericDerived3{} .assembly NonGenericDerived4{} -.class public auto ansi beforefieldinit NonGenericDerived4 extends [NonGenericDerived3]NonGenericDerived3 { } +.class public auto ansi beforefieldinit NonGenericDerived4 extends [NonGenericDerived3]NonGenericDerived3 { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il index 518534fbf7d0a6..df158c81ce452e 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il @@ -7,37 +7,112 @@ .assembly extern mscorlib { } .assembly ReOverrideMoreDerivedReturn { } -.class public auto ansi beforefieldinit A { } -.class public auto ansi beforefieldinit B extends A { } -.class public auto ansi beforefieldinit C extends B { } -.class public auto ansi beforefieldinit D extends C { } - -.class public auto ansi beforefieldinit GenRetType { } -.class public auto ansi beforefieldinit GenDerivedRetType extends class GenRetType { } -.class public auto ansi beforefieldinit Dictionary { } - -.class public auto ansi beforefieldinit GenDerive1 extends class GenRetType { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } -.class public auto ansi beforefieldinit GenDerive4 extends class GenDerive3 { } - -.class public auto ansi beforefieldinit NonGenericDerived1 extends class GenRetType { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } -.class public auto ansi beforefieldinit NonGenericDerived5 extends NonGenericDerived4 { } - -.class public auto ansi beforefieldinit GenToNonGen1 extends C { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } -.class public auto ansi beforefieldinit GenToNonGen4 extends class GenToNonGen3 { } - - -.class public auto ansi beforefieldinit NonGenThroughGen1 extends C { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } -.class public auto ansi beforefieldinit NonGenThroughGen5 extends NonGenThroughGen4 { } +.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 D extends C +{ + .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 GenDerivedRetType extends class 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 GenDerive4 extends class GenDerive3 +{ + .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 NonGenericDerived4 +{ + .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 GenToNonGen4 extends class GenToNonGen3 +{ + .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 NonGenThroughGen4 +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} .class public auto ansi beforefieldinit GenBaseType { @@ -51,7 +126,7 @@ .method public hidebysig newslot virtual instance object MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "object GenBaseType.MyFunc()" stind.ref newobj instance void A::.ctor() @@ -59,7 +134,7 @@ } .method public hidebysig newslot virtual instance class B MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.MyFunc()" stind.ref newobj instance void B::.ctor() @@ -67,7 +142,7 @@ } .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.GenToNonGen()" stind.ref newobj instance void B::.ctor() @@ -75,7 +150,7 @@ } .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.NonGenThroughGenFunc()" stind.ref newobj instance void B::.ctor() @@ -83,7 +158,7 @@ } .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType::.ctor() @@ -91,7 +166,7 @@ } .method public hidebysig newslot virtual instance class GenRetType> MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType> GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType>::.ctor() @@ -99,7 +174,7 @@ } .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.TestNonGenericDerived()" stind.ref newobj instance void class GenRetType::.ctor() diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il index b0f7fc6c7c140c..d90b4c0617a0c5 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il @@ -7,31 +7,88 @@ .assembly extern mscorlib { } .assembly ReOverrideSameReturn { } -.class public auto ansi beforefieldinit A { } -.class public auto ansi beforefieldinit B extends A { } -.class public auto ansi beforefieldinit C extends B { } +.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 { } -.class public auto ansi beforefieldinit Dictionary { } +.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 { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.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 GenToNonGen1 extends C { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.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 GenBaseType { @@ -45,7 +102,7 @@ .method public hidebysig newslot virtual instance object MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "object GenBaseType.MyFunc()" stind.ref newobj instance void A::.ctor() @@ -53,7 +110,7 @@ } .method public hidebysig newslot virtual instance class B MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.MyFunc()" stind.ref newobj instance void B::.ctor() @@ -61,7 +118,7 @@ } .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.GenToNonGen()" stind.ref newobj instance void B::.ctor() @@ -69,7 +126,7 @@ } .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.NonGenThroughGenFunc()" stind.ref newobj instance void B::.ctor() @@ -77,7 +134,7 @@ } .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType::.ctor() @@ -85,7 +142,7 @@ } .method public hidebysig newslot virtual instance class GenRetType> MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType> GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType>::.ctor() @@ -93,7 +150,7 @@ } .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.TestNonGenericDerived()" stind.ref newobj instance void class GenRetType::.ctor() diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il index 6bf44d18990117..1098912d2df1a6 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il @@ -8,31 +8,88 @@ .assembly extern mscorlib { } .assembly UnitTest { } -.class public auto ansi beforefieldinit A { } -.class public auto ansi beforefieldinit B extends A { } -.class public auto ansi beforefieldinit C extends B { } +.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 { } -.class public auto ansi beforefieldinit Dictionary { } +.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 { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.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 GenToNonGen1 extends C { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.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 GenBaseType { @@ -46,7 +103,7 @@ .method public hidebysig newslot virtual instance object MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "object GenBaseType.MyFunc()" stind.ref newobj instance void A::.ctor() @@ -54,7 +111,7 @@ } .method public hidebysig newslot virtual instance class B MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.MyFunc()" stind.ref newobj instance void B::.ctor() @@ -62,7 +119,7 @@ } .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.GenToNonGen()" stind.ref newobj instance void B::.ctor() @@ -70,7 +127,7 @@ } .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.NonGenThroughGenFunc()" stind.ref newobj instance void B::.ctor() @@ -78,7 +135,7 @@ } .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType::.ctor() @@ -86,7 +143,7 @@ } .method public hidebysig newslot virtual instance class GenRetType> MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType> GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType>::.ctor() @@ -94,7 +151,7 @@ } .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.TestNonGenericDerived()" stind.ref newobj instance void class GenRetType::.ctor() diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il index 57386432306adc..5a22dfc541b0d6 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il @@ -7,31 +7,88 @@ .assembly extern mscorlib { } .assembly UnitTestDelegates { } -.class public auto ansi beforefieldinit A { } -.class public auto ansi beforefieldinit B extends A { } -.class public auto ansi beforefieldinit C extends B { } +.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 { } -.class public auto ansi beforefieldinit Dictionary { } +.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 { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.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 GenToNonGen1 extends C { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.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 GenBaseType { @@ -45,7 +102,7 @@ .method public hidebysig newslot virtual instance object MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "object GenBaseType.MyFunc()" stind.ref newobj instance void A::.ctor() @@ -53,7 +110,7 @@ } .method public hidebysig newslot virtual instance class B MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.MyFunc()" stind.ref newobj instance void B::.ctor() @@ -61,7 +118,7 @@ } .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.GenToNonGen()" stind.ref newobj instance void B::.ctor() @@ -69,7 +126,7 @@ } .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.NonGenThroughGenFunc()" stind.ref newobj instance void B::.ctor() @@ -77,7 +134,7 @@ } .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType::.ctor() @@ -85,7 +142,7 @@ } .method public hidebysig newslot virtual instance class GenRetType> MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType> GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType>::.ctor() @@ -93,7 +150,7 @@ } .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.TestNonGenericDerived()" stind.ref newobj instance void class GenRetType::.ctor() diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il index e21b9b5217e5be..b616735304ef27 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il @@ -8,33 +8,96 @@ .assembly extern mscorlib { } .assembly UnitTest_GVM { } -.class public auto ansi beforefieldinit A { } -.class public auto ansi beforefieldinit B extends A { } -.class public auto ansi beforefieldinit C extends B { } +.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 { } -.class public auto ansi beforefieldinit Dictionary { } +.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 { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } -.class public auto ansi beforefieldinit NonGenericDerived5 extends class NonGenericDerived1 { } +.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 { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } -.class public auto ansi beforefieldinit NonGenThroughGen5 extends class NonGenThroughGen2 { } +.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 } +} .class public auto ansi beforefieldinit GenBaseType @@ -49,7 +112,7 @@ .method public hidebysig newslot virtual instance object MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "object GenBaseType.MyFunc()" stind.ref newobj instance void A::.ctor() @@ -57,7 +120,7 @@ } .method public hidebysig newslot virtual instance class B MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.MyFunc()" stind.ref newobj instance void B::.ctor() @@ -65,7 +128,7 @@ } .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.GenToNonGen()" stind.ref newobj instance void B::.ctor() @@ -73,7 +136,7 @@ } .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.NonGenThroughGenFunc()" stind.ref newobj instance void B::.ctor() @@ -81,7 +144,7 @@ } .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType::.ctor() @@ -89,7 +152,7 @@ } .method public hidebysig newslot virtual instance class GenRetType> MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType> GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType>::.ctor() @@ -97,7 +160,7 @@ } .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.TestNonGenericDerived()" stind.ref newobj instance void class GenRetType::.ctor() diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il index f4a776cd1e87a8..9c7f4e8bd3d7d9 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il @@ -8,31 +8,88 @@ .assembly extern mscorlib { } .assembly IncompatibleReturnNoValidation { } -.class public auto ansi beforefieldinit A { } -.class public auto ansi beforefieldinit B extends A { } -.class public auto ansi beforefieldinit C extends B { } +.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 { } -.class public auto ansi beforefieldinit Dictionary { } +.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 { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.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 GenToNonGen1 extends C { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.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 GenBaseType { @@ -46,7 +103,7 @@ .method public hidebysig newslot virtual instance object MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "object GenBaseType.MyFunc()" stind.ref newobj instance void A::.ctor() @@ -54,7 +111,7 @@ } .method public hidebysig newslot virtual instance class B MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.MyFunc()" stind.ref newobj instance void B::.ctor() @@ -62,7 +119,7 @@ } .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.GenToNonGen()" stind.ref newobj instance void B::.ctor() @@ -70,7 +127,7 @@ } .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.NonGenThroughGenFunc()" stind.ref newobj instance void B::.ctor() @@ -78,7 +135,7 @@ } .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType::.ctor() @@ -86,7 +143,7 @@ } .method public hidebysig newslot virtual instance class GenRetType> MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType> GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType>::.ctor() @@ -94,7 +151,7 @@ } .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.TestNonGenericDerived()" stind.ref newobj instance void class GenRetType::.ctor() diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il index 060388477f844b..c0691241610bd3 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il @@ -8,31 +8,69 @@ .assembly extern mscorlib { } .assembly OverrideSameSigAsDecl { } -.class public auto ansi beforefieldinit A { } -.class public auto ansi beforefieldinit B extends A { } -.class public auto ansi beforefieldinit C extends B { } +.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 { } -.class public auto ansi beforefieldinit Dictionary { } +.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 { } -.class public auto ansi beforefieldinit GenDerive2 extends class GenDerive1> { } -.class public auto ansi beforefieldinit GenDerive3 extends class GenDerive2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenericDerived2 extends class NonGenericDerived1 { } -.class public auto ansi beforefieldinit NonGenericDerived3 extends class NonGenericDerived2 { } -.class public auto ansi beforefieldinit NonGenericDerived4 extends NonGenericDerived3 { } +.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 GenToNonGen1 extends C { } -.class public auto ansi beforefieldinit GenToNonGen2 extends class GenToNonGen1> { } -.class public auto ansi beforefieldinit GenToNonGen3 extends class GenToNonGen2 { } +.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 { } -.class public auto ansi beforefieldinit NonGenThroughGen2 extends class NonGenThroughGen1> { } -.class public auto ansi beforefieldinit NonGenThroughGen3 extends class NonGenThroughGen2 { } -.class public auto ansi beforefieldinit NonGenThroughGen4 extends NonGenThroughGen3 { } +.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 GenBaseType { @@ -46,7 +84,7 @@ .method public hidebysig newslot virtual instance object MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "object GenBaseType.MyFunc()" stind.ref newobj instance void A::.ctor() @@ -54,7 +92,7 @@ } .method public hidebysig newslot virtual instance class B MyFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.MyFunc()" stind.ref newobj instance void B::.ctor() @@ -62,7 +100,7 @@ } .method public hidebysig newslot virtual instance class B GenToNonGen(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.GenToNonGen()" stind.ref newobj instance void B::.ctor() @@ -70,7 +108,7 @@ } .method public hidebysig newslot virtual instance class B NonGenThroughGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "B GenBaseType.NonGenThroughGenFunc()" stind.ref newobj instance void B::.ctor() @@ -78,7 +116,7 @@ } .method public hidebysig newslot virtual instance class GenRetType MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType::.ctor() @@ -86,7 +124,7 @@ } .method public hidebysig newslot virtual instance class GenRetType> MyGenFunc(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType> GenBaseType.MyGenFunc()" stind.ref newobj instance void class GenRetType>::.ctor() @@ -94,7 +132,7 @@ } .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) { - ldarg.0 + ldarg.1 ldstr "GenRetType GenBaseType.TestNonGenericDerived()" stind.ref newobj instance void class GenRetType::.ctor() From f10119d90e51c97236a1998202aa64f4441c708f Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Wed, 22 Apr 2020 16:06:39 -0700 Subject: [PATCH 03/21] Perform covariant return signature matching only after an exact match fails Fix a couple of issues in IL tests --- src/coreclr/src/vm/methodtablebuilder.cpp | 20 ++++++++----------- src/coreclr/src/vm/siginfo.cpp | 2 +- src/coreclr/src/vm/siginfo.hpp | 2 +- .../InterfaceReturns/InterfaceReturns4.il | 16 ++++++++++----- .../StructReturns/StructReturns.il | 15 +++++++++----- .../StructReturns/StructReturns2.il | 15 +++++++++----- .../CovariantReturns/UnitTest/UnitTest_GVM.il | 4 ++++ 7 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index e124da2ee66dd4..94db8febae35f9 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -2445,20 +2445,16 @@ MethodTableBuilder::EnumerateMethodImpls() BuildMethodTableThrowException(IDS_CLASSLOAD_MI_MISSING_SIG_BODY); } - BOOL allowCovariantReturn = IsEligibleForCovariantReturns(theDecl); - // Can't use memcmp because there may be two AssemblyRefs // in this scope, pointing to the same assembly, etc.). - if (!MetaSig::CompareMethodSigs( - pSigDecl, - cbSigDecl, - GetModule(), - &theDeclSubst, - pSigBody, - cbSigBody, - GetModule(), - NULL, - allowCovariantReturn)) + BOOL compatibleSignatures = MetaSig::CompareMethodSigs(pSigDecl, cbSigDecl, GetModule(), &theDeclSubst, pSigBody, cbSigBody, GetModule(), NULL, FALSE); + + if (!compatibleSignatures && IsEligibleForCovariantReturns(theDecl)) + { + compatibleSignatures = MetaSig::CompareMethodSigs(pSigDecl, cbSigDecl, GetModule(), &theDeclSubst, pSigBody, cbSigBody, GetModule(), NULL, TRUE); + } + + if (!compatibleSignatures) { BuildMethodTableThrowException(IDS_CLASSLOAD_MI_BODY_DECL_MISMATCH); } diff --git a/src/coreclr/src/vm/siginfo.cpp b/src/coreclr/src/vm/siginfo.cpp index ee16c3cb678768..dafbe670756984 100644 --- a/src/coreclr/src/vm/siginfo.cpp +++ b/src/coreclr/src/vm/siginfo.cpp @@ -3770,7 +3770,7 @@ BOOL MetaSig::GetBaseTypeTokenAndModule( } //------------------------------------------------------------------ -// Extract the base type's signature and stubstitution from the second type signature +// Extract the base type's signature and substitution from the second type signature // and recompare it with the first type's signature. //------------------------------------------------------------------ // static diff --git a/src/coreclr/src/vm/siginfo.hpp b/src/coreclr/src/vm/siginfo.hpp index a0c3de4533852e..08481222a53bc2 100644 --- a/src/coreclr/src/vm/siginfo.hpp +++ b/src/coreclr/src/vm/siginfo.hpp @@ -1100,7 +1100,7 @@ class MetaSig Module** ppBaseTypeTokenModule); //------------------------------------------------------------------ - // Extract the base type's signature and stubstitution from the second type signature + // Extract the base type's signature and substitution from the second type signature // and recompare it with the first type's signature. //------------------------------------------------------------------ static BOOL ComputeBaseTypeAndCompareElementType( diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il index 1b3ab0a5e0457e..8cb51738d8a734 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. .assembly extern System.Console { } +.assembly extern System.Runtime { } .assembly extern mscorlib { } .assembly InterfaceReturns { } @@ -153,35 +154,40 @@ { .method public static void RunTest1() noinlining { - newobj instance void class Test1::.ctor() + ldtoken class Test1 + call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) call void [System.Console]System.Console::WriteLine(object) ret } .method public static void RunTest2() noinlining { - newobj instance void class Test2::.ctor() + ldtoken class Test2 + call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) call void [System.Console]System.Console::WriteLine(object) ret } .method public static void RunTest3() noinlining { - newobj instance void class Test3::.ctor() + ldtoken class Test3 + call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) call void [System.Console]System.Console::WriteLine(object) ret } .method public static void RunTest4() noinlining { - newobj instance void class Test4::.ctor() + ldtoken class Test4 + call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) call void [System.Console]System.Console::WriteLine(object) ret } .method public static void RunTest5() noinlining { - newobj instance void class Test5::.ctor() + ldtoken class Test5 + call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) call void [System.Console]System.Console::WriteLine(object) ret } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il index 744dd316b2a8fb..f1bb9d3f53c973 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il @@ -88,27 +88,32 @@ { .method public hidebysig newslot virtual instance valuetype A MyFunc() { - ldnull + .locals ( [0] valuetype A ) + ldloc.0 ret } .method public hidebysig newslot virtual instance valuetype A GenToNonGen() { - ldnull + .locals ( [0] valuetype A ) + ldloc.0 ret } .method public hidebysig newslot virtual instance valuetype A NonGenThroughGenFunc() { - ldnull + .locals ( [0] valuetype A ) + ldloc.0 ret } .method public hidebysig newslot virtual instance valuetype GenStruct MyGenFunc() { - ldnull + .locals ( [0] valuetype GenStruct ) + ldloc.0 ret } .method public hidebysig newslot virtual instance valuetype GenStruct> MyGenFunc() { - ldnull + .locals ( [0] valuetype GenStruct> ) + ldloc.0 ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il index d403cb1a33af9b..1a76008e24b275 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il @@ -119,7 +119,8 @@ .method public hidebysig newslot virtual instance valuetype A NonGenThroughGenOverride() { .override method instance class NonGenThroughGen4 class BaseType::NonGenThroughGenFunc() - ldnull + .locals ( [0] valuetype A ) + ldloc.0 ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } @@ -130,7 +131,8 @@ .method public hidebysig newslot virtual instance valuetype A GenToNonGenOverride() { .override method instance class GenToNonGen3 class BaseType::GenToNonGen() - ldnull + .locals ( [0] valuetype A ) + ldloc.0 ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } @@ -141,7 +143,8 @@ .method public hidebysig newslot virtual instance valuetype GenStruct NewGenFunc1() { .override method instance class NonGenericDerived4 class BaseType::MyGenFunc() - ldnull + .locals ( [0] valuetype GenStruct ) + ldloc.0 ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } @@ -152,7 +155,8 @@ .method public hidebysig newslot virtual instance valuetype GenStruct> NewGenFunc1() { .override method instance class GenDerive3 class BaseType::MyGenFunc() - ldnull + .locals ( [0] valuetype GenStruct> ) + ldloc.0 ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } @@ -163,7 +167,8 @@ .method public hidebysig newslot virtual instance valuetype A NewFunc2() { .override method instance class C class BaseType::MyFunc() - ldnull + .locals ( [0] valuetype A ) + ldloc.0 ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il index b616735304ef27..398f35987f7cbf 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il @@ -312,6 +312,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Invalid2 extends class GenMiddleType { @@ -324,6 +325,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Invalid3 extends class GenMiddleType { @@ -336,6 +338,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Invalid4 extends class GenMiddleType { @@ -348,6 +351,7 @@ ldnull ret } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } // ======================================================================================== From 8d5d87e5dc9348552fb06b1436daf0ee953afa0c Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Thu, 23 Apr 2020 12:33:42 -0700 Subject: [PATCH 04/21] Add test coverage for implicit override with less derived return type --- .../ImplicitOverrideSameSigAsDecl.il | 562 ++++++++++++++++++ .../ImplicitOverrideSameSigAsDecl.ilproj | 10 + 2 files changed, 572 insertions(+) create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.ilproj diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il new file mode 100644 index 00000000000000..221226b62af0ac --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il @@ -0,0 +1,562 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Private.CoreLib { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly ImplicitOverrideSameSigAsDecl { } + +.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 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 GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + 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 + } + .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) + { + ldarg.1 + ldstr "GenRetType GenBaseType.TestNonGenericDerived()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } +} + + +// ======================================================================================== + +.class public auto ansi beforefieldinit GenTestType extends class GenBaseType +{ + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + { + .override method instance class B class GenBaseType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 TestType.NewGenFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) + { + .override method instance object class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "GenRetType TestType.NewFunc1()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + { + .override method instance class B class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "C TestType.NewFunc2()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + .maxstack 8 + ldarg.0 + call instance void class GenBaseType::.ctor() + ret + } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit DerivedTestType extends class GenTestType +{ + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + + .method public hidebysig virtual instance object MyFunc(string& res) + { + ldarg.1 + ldstr "object DerivedTestType.MyFunc()" + stind.ref + newobj instance void A::.ctor() + ret + } + + .method public hidebysig virtual instance class B MyFunc(string& res) + { + ldarg.1 + ldstr "B DerivedTestType.MyFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + + .method public hidebysig virtual instance class B GenToNonGen(string& res) + { + ldarg.1 + ldstr "B DerivedTestType.GenToNonGen()" + stind.ref + newobj instance void B::.ctor() + ret + } + + .method public hidebysig virtual instance class B NonGenThroughGenFunc(string& res) + { + ldarg.1 + ldstr "B DerivedTestType.NonGenThroughGenFunc()" + stind.ref + newobj instance void B::.ctor() + ret + } + + .method public hidebysig virtual instance class GenRetType MyGenFunc(string& res) + { + ldarg.1 + ldstr "GenRetType DerivedTestType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } + + .method public hidebysig virtual instance class GenRetType> MyGenFunc(string& res) + { + ldarg.1 + ldstr "GenRetType> DerivedTestType.MyGenFunc()" + stind.ref + newobj instance void class GenRetType>::.ctor() + ret + } + + .method public hidebysig virtual instance class GenRetType TestNonGenericDerived(string& res) + { + ldarg.1 + ldstr "GenRetType DerivedTestType.TestNonGenericDerived()" + stind.ref + newobj instance void class GenRetType::.ctor() + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static bool RunTest1() noinlining + { + .locals init (string res, bool flag, string expected) + + ldstr "object DerivedTestType.MyFunc()" + stloc.2 + + ldstr "EXPECTED: " + call void [System.Console]System.Console::Write(object) + ldloc.2 + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class DerivedTestType::.ctor() + ldloca.s 0 + callvirt instance object class GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldloc.2 + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest2() noinlining + { + .locals init (string res, bool flag, string expected) + + ldstr "B DerivedTestType.MyFunc()" + stloc.2 + + ldstr "EXPECTED: " + call void [System.Console]System.Console::Write(object) + ldloc.2 + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class DerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::MyFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldloc.2 + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest3() noinlining + { + .locals init (string res, bool flag, string expected) + + ldstr "B DerivedTestType.GenToNonGen()" + stloc.2 + + ldstr "EXPECTED: " + call void [System.Console]System.Console::Write(object) + ldloc.2 + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class DerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::GenToNonGen(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldloc.2 + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest4() noinlining + { + .locals init (string res, bool flag, string expected) + + ldstr "B DerivedTestType.NonGenThroughGenFunc()" + stloc.2 + + ldstr "EXPECTED: " + call void [System.Console]System.Console::Write(object) + ldloc.2 + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class DerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldloc.2 + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest5() noinlining + { + .locals init (string res, bool flag, string expected) + + ldstr "GenRetType DerivedTestType.MyGenFunc()" + stloc.2 + + ldstr "EXPECTED: " + call void [System.Console]System.Console::Write(object) + ldloc.2 + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class DerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldloc.2 + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest6() noinlining + { + .locals init (string res, bool flag, string expected) + + ldstr "GenRetType> DerivedTestType.MyGenFunc()" + stloc.2 + + ldstr "EXPECTED: " + call void [System.Console]System.Console::Write(object) + ldloc.2 + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class DerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldloc.2 + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public static bool RunTest7() noinlining + { + .locals init (string res, bool flag, string expected) + + ldstr "GenRetType DerivedTestType.TestNonGenericDerived()" + stloc.2 + + ldstr "EXPECTED: " + call void [System.Console]System.Console::Write(object) + ldloc.2 + call void [System.Console]System.Console::WriteLine(object) + ldstr "ACTUAL : " + call void [System.Console]System.Console::Write(object) + + newobj instance void class DerivedTestType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType class GenBaseType::TestNonGenericDerived(string&) + pop + + ldloc.0 + call void [System.Console]System.Console::WriteLine(object) + + ldloc.0 + ldloc.2 + call bool [System.Runtime]System.String::op_Equality(string, string) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + T1: + call bool CMain::RunTest1() + brtrue.s T2 + ldc.i4.0 + stloc.0 + + T2: + call bool CMain::RunTest2() + brtrue.s T3 + ldc.i4.0 + stloc.0 + + T3: + call bool CMain::RunTest3() + brtrue.s T4 + ldc.i4.0 + stloc.0 + + T4: + call bool CMain::RunTest4() + brtrue.s T5 + ldc.i4.0 + stloc.0 + + T5: + call bool CMain::RunTest5() + brtrue.s T6 + ldc.i4.0 + stloc.0 + + T6: + call bool CMain::RunTest6() + brtrue.s T7 + ldc.i4.0 + stloc.0 + + T7: + call bool CMain::RunTest7() + brtrue.s DONE + ldc.i4.0 + stloc.0 + + DONE: + + ldloc.0 + brtrue.s PASS + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + 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/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.ilproj new file mode 100644 index 00000000000000..20cae0e097a067 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + From a14af6f42b5a4c09b9d4d151ba176464d1828c7c Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Thu, 23 Apr 2020 14:09:04 -0700 Subject: [PATCH 05/21] Change ValidateMethodImplRemainsInEffect attribute to apply to methods --- src/coreclr/src/vm/class.cpp | 17 +++++++----- .../CovariantReturns/UnitTest/UnitTest.il | 14 +++++++--- .../CovariantReturns/UnitTest/UnitTest_GVM.il | 26 ++++++++++--------- .../ImplicitOverrideSameSigAsDecl.il | 16 ++++++++++-- .../IncompatibleReturnNoValidation.il | 2 +- .../Validation/OverrideSameSigAsDecl.il | 18 +++++-------- ...idateMethodImplRemainsInEffectAttribute.cs | 2 +- 7 files changed, 56 insertions(+), 39 deletions(-) diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index 1a71a594047d8a..299011926e9304 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -994,18 +994,21 @@ void ClassLoader::ValidateMethodImplRemainsInEffect(MethodTable* pMT) if (pParentMT == NULL) RETURN; - // If the ValidateMethodImplRemainsInEffect attribute does not exist on the type, it will not be validated. - BYTE* pVal = NULL; - ULONG cbVal = 0; - HRESULT hr = pMT->GetCustomAttribute(WellKnownAttribute::ValidateMethodImplRemainsInEffectAttribute, (const void**)&pVal, &cbVal); - if (hr != S_OK) - RETURN; - for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++) { MethodDesc* pMD = pMT->GetMethodDescForSlot(i); MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i); + // Validation only applicable to MethodImpls + if (!pMD->IsMethodImpl()) + continue; + + // If the ValidateMethodImplRemainsInEffect attribute does not exist on the method, it will not be validated. + BYTE* pVal = NULL; + ULONG cbVal = 0; + if (pMD->GetCustomAttribute(WellKnownAttribute::ValidateMethodImplRemainsInEffectAttribute, (const void**)&pVal, &cbVal) != S_OK) + continue; + DWORD originalIndex = pMD->GetSlot(); if (originalIndex == i) continue; diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il index 1098912d2df1a6..21f3108701e9b9 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il @@ -164,8 +164,6 @@ .class public auto ansi beforefieldinit GenMiddleType extends class GenBaseType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 @@ -176,6 +174,7 @@ .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenOverride_Middle(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldarg.1 ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" @@ -186,6 +185,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGenOverride_Middle(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 ldstr "GenToNonGen1> GenMiddleType.GenToNonGenOverride()" @@ -196,6 +196,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived1 NewGenFunc1_Middle(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "NonGenericDerived1 GenMiddleType.NewGenFunc1()" @@ -206,6 +207,7 @@ .method public hidebysig newslot virtual instance class GenDerive1> NewGenFunc2_Middle(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "GenDerive1> GenMiddleType.NewGenFunc2()" @@ -220,10 +222,9 @@ .class public auto ansi beforefieldinit GenTestType extends class GenMiddleType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldarg.1 ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" @@ -234,6 +235,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" @@ -244,6 +246,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "NonGenericDerived4 TestType.NewGenFunc1()" @@ -254,6 +257,7 @@ .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "GenDerive3 TestType.NewGenFunc2()" @@ -264,6 +268,7 @@ .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance object class GenBaseType::MyFunc(string& res) ldarg.1 ldstr "GenRetType TestType.NewFunc1()" @@ -274,6 +279,7 @@ .method public hidebysig newslot virtual instance class C NewFunc2(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc(string& res) ldarg.1 ldstr "C TestType.NewFunc2()" diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il index 398f35987f7cbf..5edc688108eaf1 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il @@ -173,8 +173,6 @@ .class public auto ansi beforefieldinit GenMiddleType extends class GenBaseType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 @@ -185,6 +183,7 @@ .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenOverride_Middle(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) ldarg.1 ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" @@ -195,6 +194,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGenOverride_Middle(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) ldarg.1 ldstr "GenToNonGen1> GenMiddleType.GenToNonGenOverride()" @@ -205,6 +205,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived1 NewGenFunc1_Middle(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) ldarg.1 ldstr "NonGenericDerived1 GenMiddleType.NewGenFunc1()" @@ -215,6 +216,7 @@ .method public hidebysig newslot virtual instance class GenDerive2 NewGenFunc2_Middle(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) ldarg.1 ldstr "GenDerive2 GenMiddleType.NewGenFunc2()" @@ -228,10 +230,9 @@ .class public auto ansi beforefieldinit GenTestType extends class GenMiddleType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig newslot virtual instance class NonGenThroughGen5 NonGenThroughGenOverride(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) ldarg.1 ldstr "NonGenThroughGen5 TestType.NonGenThroughGenFunc()" @@ -242,6 +243,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) ldarg.1 ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" @@ -252,6 +254,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived5 NewGenFunc1(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) ldarg.1 ldstr "NonGenericDerived5 TestType.NewGenFunc1()" @@ -262,6 +265,7 @@ .method public hidebysig newslot virtual instance class GenDerive2 NewGenFunc2(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) ldarg.1 ldstr "GenDerive2 TestType.NewGenFunc2()" @@ -272,6 +276,7 @@ .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance object class GenBaseType::MyFunc<[1]>(string& res) ldarg.1 ldstr "GenRetType TestType.NewFunc1()" @@ -282,6 +287,7 @@ .method public hidebysig newslot virtual instance class C NewFunc2(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc<[1]>(string& res) ldarg.1 ldstr "C TestType.NewFunc2()" @@ -303,11 +309,10 @@ .class public auto ansi beforefieldinit Invalid1 extends class GenMiddleType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - // 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) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) ldnull ret @@ -316,11 +321,10 @@ } .class public auto ansi beforefieldinit Invalid2 extends class GenMiddleType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - // Invalid: when comparing 'object' with !!Y in the instantiation .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) ldnull ret @@ -329,11 +333,10 @@ } .class public auto ansi beforefieldinit Invalid3 extends class GenMiddleType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - // Invalid when comparing !!Y and 'object' in instantiation of GenRetType .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) ldnull ret @@ -342,11 +345,10 @@ } .class public auto ansi beforefieldinit Invalid4 extends class GenMiddleType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - // Invalid when comparing !!Y and 'string' in instantiation of Dictionary .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) ldnull ret diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il index 221226b62af0ac..3dbed8ce83a035 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il @@ -218,10 +218,10 @@ .class public auto ansi beforefieldinit DerivedTestType extends class GenTestType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig virtual instance object MyFunc(string& res) { + // Attribute ignored since this is not a MethodImpl + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) ldarg.1 ldstr "object DerivedTestType.MyFunc()" stind.ref @@ -231,6 +231,8 @@ .method public hidebysig virtual instance class B MyFunc(string& res) { + // Attribute ignored since this is not a MethodImpl + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) ldarg.1 ldstr "B DerivedTestType.MyFunc()" stind.ref @@ -240,6 +242,8 @@ .method public hidebysig virtual instance class B GenToNonGen(string& res) { + // Attribute ignored since this is not a MethodImpl + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) ldarg.1 ldstr "B DerivedTestType.GenToNonGen()" stind.ref @@ -249,6 +253,8 @@ .method public hidebysig virtual instance class B NonGenThroughGenFunc(string& res) { + // Attribute ignored since this is not a MethodImpl + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) ldarg.1 ldstr "B DerivedTestType.NonGenThroughGenFunc()" stind.ref @@ -258,6 +264,8 @@ .method public hidebysig virtual instance class GenRetType MyGenFunc(string& res) { + // Attribute ignored since this is not a MethodImpl + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) ldarg.1 ldstr "GenRetType DerivedTestType.MyGenFunc()" stind.ref @@ -267,6 +275,8 @@ .method public hidebysig virtual instance class GenRetType> MyGenFunc(string& res) { + // Attribute ignored since this is not a MethodImpl + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) ldarg.1 ldstr "GenRetType> DerivedTestType.MyGenFunc()" stind.ref @@ -276,6 +286,8 @@ .method public hidebysig virtual instance class GenRetType TestNonGenericDerived(string& res) { + // Attribute ignored since this is not a MethodImpl + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) ldarg.1 ldstr "GenRetType DerivedTestType.TestNonGenericDerived()" stind.ref diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il index 9c7f4e8bd3d7d9..d0d62a5df0952e 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il @@ -239,7 +239,7 @@ // The following types are overriding base type methods that have already been overridden // with covariant return types, but the return type here is not compatible (return type is // a base type of the covariant return type of existing overrides). Validation is only -// triggered by the presense of the ValidateMethodImplRemainsInEffect attribute, so the +// triggered by the presence of the ValidateMethodImplRemainsInEffect attribute, so the // following types should successfully load since they do not have the attribute. // ======================================================================================== .class public auto ansi beforefieldinit IncompatibleButValid1 extends class GenTestType diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il index c0691241610bd3..2c8a0cb50aebf5 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il @@ -218,10 +218,9 @@ .class public auto ansi beforefieldinit Invalid1 extends class GenTestType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride_Invalid(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldnull ret @@ -238,10 +237,9 @@ .class public auto ansi beforefieldinit Invalid2 extends class GenTestType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig newslot virtual instance class B GenToNonGenOverride_Invalid(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldnull ret @@ -258,10 +256,9 @@ .class public auto ansi beforefieldinit Invalid3 extends class GenTestType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1_Invalid(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldnull ret @@ -278,10 +275,9 @@ .class public auto ansi beforefieldinit Invalid4 extends class GenTestType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2_Invalid(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldnull ret @@ -298,10 +294,9 @@ .class public auto ansi beforefieldinit Invalid5 extends class GenTestType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig newslot virtual instance object NewFunc1_Invalid(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance object class GenBaseType::MyFunc(string& res) ldnull ret @@ -318,10 +313,9 @@ .class public auto ansi beforefieldinit Invalid6 extends class GenTestType { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - .method public hidebysig newslot virtual instance class B NewFunc2_Invalid(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc(string& res) ldnull ret diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs index 2da77ceb45fe9f..c289981fdd58df 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs @@ -4,7 +4,7 @@ namespace System.Runtime.CompilerServices { - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public sealed class ValidateMethodImplRemainsInEffectAttribute : Attribute { } From 0e4e4726cd9a3e5f1deb5541f042696035bf7a4a Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Wed, 29 Apr 2020 11:53:51 -0700 Subject: [PATCH 06/21] Moving covariant return type checking to the final stage of type loading, and use CanCastTo instead of signature-based checking, to be allow for type compatibility based on ECMA I.8.7.1. Fixed behavior of the ValidateMethodImplRemainsInEffectAttribute. Updates to tests --- .../features/covariant-return-methods.md | 69 +- src/coreclr/src/inc/sigbuilder.h | 2 - src/coreclr/src/utilcode/sigbuilder.cpp | 16 - src/coreclr/src/vm/class.cpp | 165 ++- src/coreclr/src/vm/clsload.hpp | 2 +- src/coreclr/src/vm/method.hpp | 28 +- src/coreclr/src/vm/methodtablebuilder.cpp | 22 +- src/coreclr/src/vm/methodtablebuilder.h | 1 + src/coreclr/src/vm/siginfo.cpp | 570 +------- src/coreclr/src/vm/siginfo.hpp | 58 +- .../InterfaceReturns/InterfaceReturns.il | 363 ----- .../InterfaceReturns/InterfaceReturns.ilproj | 10 - .../InterfaceReturns/InterfaceReturns2.il | 307 ---- .../InterfaceReturns/InterfaceReturns2.ilproj | 10 - .../InterfaceReturns/InterfaceReturns3.il | 315 ---- .../InterfaceReturns/InterfaceReturns3.ilproj | 10 - .../InterfaceReturns/InterfaceReturns4.il | 316 ---- .../InterfaceReturns/InterfaceReturns4.ilproj | 10 - .../ImplicitOverrideSameSigAsDecl.il} | 377 ++--- .../ImplicitOverrideSameSigAsDecl.ilproj | 0 .../OverrideSameSigAsDecl.il | 79 +- .../OverrideSameSigAsDecl.ilproj | 0 .../StructReturns/StructReturns.il | 338 ----- .../StructReturns/StructReturns2.il | 338 ----- .../StructReturns/StructReturns2.ilproj | 10 - .../UnitTest/AttributeTesting.il | 1281 +++++++++++++++++ .../AttributeTesting.ilproj} | 2 +- .../UnitTest/OverrideMoreDerivedReturn.il | 372 +++-- .../UnitTest/OverrideSameReturn.il | 519 ------- .../UnitTest/OverrideSameReturn.ilproj | 10 - .../CovariantReturns/UnitTest/UnitTest.il | 1102 +++++++++++--- .../CovariantReturns/UnitTest/UnitTest_GVM.il | 478 +++--- .../ImplicitOverrideSameSigAsDecl.il | 574 -------- .../IncompatibleReturnNoValidation.ilproj | 10 - 34 files changed, 3255 insertions(+), 4509 deletions(-) delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.ilproj delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.ilproj delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.ilproj delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.ilproj rename src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/{Validation/IncompatibleReturnNoValidation.il => ReturnTypeValidation/ImplicitOverrideSameSigAsDecl.il} (52%) rename src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/{Validation => ReturnTypeValidation}/ImplicitOverrideSameSigAsDecl.ilproj (100%) rename src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/{Validation => ReturnTypeValidation}/OverrideSameSigAsDecl.il (89%) rename src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/{Validation => ReturnTypeValidation}/OverrideSameSigAsDecl.ilproj (100%) delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il rename src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/{StructReturns/StructReturns.ilproj => UnitTest/AttributeTesting.ilproj} (83%) delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.ilproj delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.ilproj diff --git a/docs/design/features/covariant-return-methods.md b/docs/design/features/covariant-return-methods.md index 64c79b53afb2db..0bc9c541cbf839 100644 --- a/docs/design/features/covariant-return-methods.md +++ b/docs/design/features/covariant-return-methods.md @@ -2,47 +2,60 @@ Covariant return methods is a runtime feature designed to support the [covariant return types](https://github.com/dotnet/csharplang/blob/master/proposals/covariant-returns.md) and [records](https://github.com/dotnet/csharplang/blob/master/proposals/records.md) C# language features posed for C# 9.0. -This feature allows an overriding method to have a more derived reference type than the method it overrides. Covariant return methods can only be described through MethodImpl records, and as an initial implementation, will have the following limitations: -1. Covariant return methods will only be applicable to methods on reference types: the MethodDecl and MethodImpl records can only be on reference types. Methods on interfaces will not be supported. -2. Return types in covariant return methods can only be reference types: covariant interface return types are not supported. +This feature allows an overriding method to have a return type that is different than the one on the method it overrides, but compatible with it. The type compability rules are defined in ECMA I.8.7.1. Example: using a more derived return type. The only exception applicable to this rule for this feature is the compatibility between a value type and an interface that it implements, and this is due to the difference in ABI between reference types and value types (unboxed value types can be returned through a hidden return buffer parameter). -Supporting interfaces comes with many complications (ex: interface equivalence, default interface methods, variance on generic interfaces, etc...), which is why the feature will initially only support classes. +Covariant return methods can only be described through MethodImpl records, and as an initial implementation will only be applicable to methods on reference types. Methods on interfaces and value types will not be supported (may be supported later in the future). -MethodImpl checking will allow a return type to vary as long as the override is compatible with the return type of the method overriden (i.e. a derived type). +MethodImpl checking will allow a return type to vary as long as the override is compatible with the return type of the method overriden (ECMA I.8.7.1). If a language wishes for the override to be semantically visible such that users of the more derived type may rely on the covariant return type it shall make the override a newslot method with appropriate visibility AND name to be used outside of the class. For virtual method slot MethodImpl overrides, each slot shall be checked for compatible signature on type load. (Implementation note: This behavior can be triggered only if the type has a covariant return type override in its hierarchy, so as to make this pay for play.) -A new `ValidateMethodImplRemainsInEffectAttribute` shall be added. The presence of this attribute is to require the type loader to ensure that the MethodImpl records specified on the method have not lost their slot unifying behavior due to other actions. In other words, when a MethodImpl on type A overrides some method using a derived return type in the signature, any type deriving from A will be allowed to have a MethodImpl record that overrides the same method as long as the return type used in the signature is the same or more derived than the return type used in the MethodImpl signature on type A. This is used to allow the C# language to require that overrides have the consistent behaviors expected. The expectation is that C# would place this attribute on covariant override methods in classes. +A new `ValidateMethodImplRemainsInEffectAttribute` shall be added. The presence of this attribute is to require the type loader to ensure that the MethodImpl records specified on the method have not lost their slot unifying behavior due to other actions. This is used to allow the C# language to require that overrides have the consistent behaviors expected. The expectation is that C# would place this attribute on covariant override methods in classes. ## Implementation Notes -### Signature Checking - -Signature checking for MethodImpl is done through the `MetaSig::CompareElementType` method, which is called from various places in the runtime when comparing method signatures. This method compares the signatures of two types, and will now take a boolean flag that would allow for derived type checking behavior. The boolean flag will be set to `TRUE` appropriately during comparison of the return type signatures between a MethodImpl and MethodDecl records. - -The type signature checking algorithm will perform the following: -1. Traverse and compare the signatures for `type1` and `type2` recursively. -2. If the signatures mismatch at any given point, and the current element type for `type2` is `ELEMENT_TYPE_CLASS` or `ELEMENT_TYPE_GENERICINST`: - + Check if base type comparison is allowed - + Compute the parent type's signature and parent type's generic substitution of `type2` - + Perform a recursive call to re-compare `type1` with the new parent type signature of `type2`. - -Note: if `ELEMENT_TYPE_INTERNAL` is encountered in either of the type signatures, both types will be fully loaded and compared for compatibility. - -### VTable Slot Validation +### Return Type Checking + +During enumeration of MethodImpls on a type (`MethodTableBuilder::EnumerateMethodImpls()`), if the signatures of the MethodImpl and the MethodDecl do not match: +1. We repeat the signature comparison a second time, but skip the comparison of the return type signatures. If the signatures for the rest of the method arguments match, we will conditionally treat that MethodImpl as a valid one, but flag it for a closer examination of the return type compatibility at a later stage of type loading (end of `CLASS_LOAD_EXACTPARENTS` stage). +2. At the end of the `CLASS_LOAD_EXACTPARENTS` type loading stage, examing each virtual method on the type, and if it has been flagged for further return type checking: + + Load the `TypeHandle` of the return type of the method on base type. + + Load the `TypeHandle` of the return type of the method on the current type being validated. + + Verify that the second `TypeHandle` is compatible with the first `TypeHandle` using the `MethodTable::CanCastTo()` API. If they are not compatible, a TypeLoadException is thrown. + +Once a method is flagged for return type checking, every time the vtable slot containing that method gets overridden on a derived type, the new override will also be checked for compatiblity. This is to ensure that no derived type can implicitly override some virtual method that has already been overridden by some MethodImpl with a covariant return type. + +### VTable Slot Unification + +If a MethodImpl has the `ValidateMethodImplRemainsInEffectAttribute` attribute, it needs to propagate all applicable vtable slots on the type. This is to ensure that if we use the signature of one of the base type methods to call the overriding method, we still execute the overriding method. + +Consider this case: +``` C# + class A { + RetType VirtualFunction() { } + } + class B : A { + [ValidateMethodImplRemainsInEffect] + DerivedRetType VirtualFunction() { .override A.VirtualFuncion } + } + class C : B { + [ValidateMethodImplRemainsInEffect] + MoreDerivedRetType VirtualFunction() { .override A.VirtualFunction } + } +``` -Validation will only be performed if the `ValidateMethodImplRemainsInEffectAttribute` exists on the type that needs validation. Validation is only performed on the type where the attribute is added, and does not propagate to its base or derived types (every type that needs to be validated needs to have this attribute). +Given an object of type `C`, the attribute will ensure that: +``` C# + callvirt RetType A::VirtualFunc() -> executes the MethodImpl on C + callvirt DerivedRetType B::VirtualFunc() -> executes the MethodImpl on C + callvirt MoreDerivedRetType C::VirtualFunc() -> executes the MethodImpl on C +``` -Validation is performed at the very last step of `CLASS_LOAD_EXACTPARENTS`, after all base types have been loaded, and the vtable has been fully built. +Without the attribute, the second callvirt would normally execute the MethodImpl on `B` (the MethodImpl on `C` does not override the vtable slot of `B`'s MethodImpl, but only overrides the declaring method's vtable slot. -The validation algorithm will perform the following: -1. For each slot in the vtable that also exists in the vtable of the base type: - + Check if the `MethodDesc` on that slot has a different original slot value. If not, continue. - + Let `hType1` be the `TypeHandle` of the return type of the method on base type. - + Let `hType2` be the `TypeHandle` of the return type of the method on the current type being validated. - + Verify that `hType2` is the same type as, or a derived type of `hType1` +This slot unification step will also take place during the last step of type loading (end of `CLASS_LOAD_EXACTPARENTS` stage). ### [Future] Interface Support diff --git a/src/coreclr/src/inc/sigbuilder.h b/src/coreclr/src/inc/sigbuilder.h index 938e50d8f31346..c1ad67af0f2e34 100644 --- a/src/coreclr/src/inc/sigbuilder.h +++ b/src/coreclr/src/inc/sigbuilder.h @@ -74,8 +74,6 @@ class SigBuilder } void AppendBlob(const PVOID pBlob, SIZE_T cbBlob); - - void AppendSignature(const PCCOR_SIGNATURE pSig, const PCCOR_SIGNATURE pSigEnd); }; #endif // _SIGBUILDER_H_ diff --git a/src/coreclr/src/utilcode/sigbuilder.cpp b/src/coreclr/src/utilcode/sigbuilder.cpp index 58d0c374cf66a0..922e1613ca3697 100644 --- a/src/coreclr/src/utilcode/sigbuilder.cpp +++ b/src/coreclr/src/utilcode/sigbuilder.cpp @@ -119,22 +119,6 @@ void SigBuilder::AppendBlob(const PVOID pBlob, SIZE_T cbBlob) m_dwLength += (DWORD)cbBlob; } -void SigBuilder::AppendSignature(const PCCOR_SIGNATURE pSig, const PCCOR_SIGNATURE pSigEnd) -{ - STANDARD_VM_CONTRACT; - - // Overflow checks - if (pSigEnd < pSig) - ThrowOutOfMemory(); - - DWORD cbSig = (DWORD)(pSigEnd - pSig); - - Ensure(cbSig); - memcpy(&m_pBuffer[m_dwLength], pSig, cbSig); - - m_dwLength += cbSig; -} - void SigBuilder::Grow(SIZE_T cbMin) { STANDARD_VM_CONTRACT; diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index 299011926e9304..ee5c61dfd13c20 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -967,7 +967,7 @@ void ClassLoader::LoadExactParents(MethodTable *pMT) MethodTableBuilder::CopyExactParentSlots(pMT, pApproxParentMT); - ValidateMethodImplRemainsInEffect(pMT); + ValidateMethodsWithCovariantReturnTypes(pMT); // We can now mark this type as having exact parents pMT->SetHasExactParent(); @@ -976,50 +976,79 @@ void ClassLoader::LoadExactParents(MethodTable *pMT) } /*static*/ -void ClassLoader::ValidateMethodImplRemainsInEffect(MethodTable* pMT) +void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) { - CONTRACT_VOID + CONTRACTL { STANDARD_VM_CHECK; PRECONDITION(CheckPointer(pMT)); } - CONTRACT_END; + CONTRACTL_END; + + // + // Validation for methods with covariant return types is a two step process. + // + // The first step is to validate that the return types on overriding methods with covariant return types are + // compatible with the return type of the method being overridden. Compatibility rules are defined by + // ECMA I.8.7.1, which is what the CanCastTo() API checks. + // + // The second step is to propagate an overriding MethodImpl to all applicable vtable slots if the MethodImpl + // has the ValidateMethodImplRemainsInEffect attribute. This is to ensure that if we use the signature of one of + // the base type methods to call the overriding method, we still execute the overriding method. + // + // Consider this case: + // + // class A { + // RetType VirtualFunction() { } + // } + // class B : A { + // [ValidateMethodImplRemainsInEffect] + // DerivedRetType VirtualFunction() { .override A.VirtualFuncion } + // } + // class C : B { + // MoreDerivedRetType VirtualFunction() { .override A.VirtualFunction } + // } + // + // NOTE: Typically the attribute would be added to the MethodImpl on C, but was omitted in this example to + // illustrate how its presence on a MethodImpl on the base type can propagate as well. In other words, + // think of it as applying to the vtable slot itself, so any MethodImpl that overrides this slot on a + // derived type will propagate to all other applicable vtable slots. + // + // Given an object of type C, the attribute will ensure that: + // callvirt RetType A::VirtualFunc() -> executes the MethodImpl on C + // callvirt DerivedRetType B::VirtualFunc() -> executes the MethodImpl on C + // callvirt MoreDerivedRetType C::VirtualFunc() -> executes the MethodImpl on C + // + // Without the attribute, the second callvirt would normally execute the MethodImpl on B (the MethodImpl on + // C does not override the vtable slot of B's MethodImpl, but only overrides the declaring method's vtable slot. + // // Validation not applicable to interface types and value types, since these are not currently // supported with the covariant return feature if (pMT->IsInterface() || pMT->IsValueType()) - RETURN; + return; MethodTable* pParentMT = pMT->GetParentMethodTable(); if (pParentMT == NULL) - RETURN; + return; + + // Step 1: Validate compatibility of return types on overriding methods for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++) { MethodDesc* pMD = pMT->GetMethodDescForSlot(i); MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i); - // Validation only applicable to MethodImpls - if (!pMD->IsMethodImpl()) - continue; - - // If the ValidateMethodImplRemainsInEffect attribute does not exist on the method, it will not be validated. - BYTE* pVal = NULL; - ULONG cbVal = 0; - if (pMD->GetCustomAttribute(WellKnownAttribute::ValidateMethodImplRemainsInEffectAttribute, (const void**)&pVal, &cbVal) != S_OK) - continue; - - DWORD originalIndex = pMD->GetSlot(); - if (originalIndex == i) + if (pMD == pParentMD) continue; - DWORD originalIndexParent = pParentMD->GetSlot(); - if (originalIndex == originalIndexParent) + if (!pMD->RequiresCovariantReturnTypeChecking() && !pParentMD->RequiresCovariantReturnTypeChecking()) continue; - // If we reach this point, it means we have a MethodImpl override. With the covariant return feature, the presense of the - // ValidateMethodImplRemainsInEffect attribute is used to validate that if a method gets overridden, the return type - // in the new override is the same type or a more derived type as the return type of the method being overriden. + // If the bit is not set on this method, but we reach here because it's been set on the method at the same slot on + // the base type, set the bit for the current method to ensure any future overriding method down the chain gets checked. + if (!pMD->RequiresCovariantReturnTypeChecking()) + pMD->SetRequiresCovariantReturnTypeChecking(); // The context used to load the return type of the parent method has to use the generic method arguments // of the overriding method, otherwise the type comparison below will not work correctly @@ -1031,33 +1060,87 @@ void ClassLoader::ValidateMethodImplRemainsInEffect(MethodTable* pMT) MetaSig methodSig2(pMD); TypeHandle hType2 = methodSig2.GetReturnProps().GetTypeHandleThrowing(pMD->GetModule(), &context2, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS); - // Type1 has to be equal to Type2, or a base type of Type2 (covariant returns) + _ASSERTE(hType1.GetMethodTable() != NULL); + _ASSERTE(hType2.GetMethodTable() != NULL); - if (!MetaSig::CompareTypeHandles(hType1, hType2, TRUE /* allowDerivedClass */ )) { - SString strAssemblyName; - pMD->GetAssembly()->GetDisplayName(strAssemblyName); + GCX_COOP(); - SString strInvalidTypeName; - TypeString::AppendType(strInvalidTypeName, TypeHandle(pMD->GetMethodTable())); + TypeHandlePairList visited(hType1, hType2, NULL); + if (!hType2.GetMethodTable()->CanCastTo(hType1.GetMethodTable(), &visited)) + { + SString strAssemblyName; + pMD->GetAssembly()->GetDisplayName(strAssemblyName); + + SString strInvalidTypeName; + TypeString::AppendType(strInvalidTypeName, TypeHandle(pMD->GetMethodTable())); - SString strInvalidMethodName; - TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation()); + SString strInvalidMethodName; + TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation()); - SString strParentMethodName; - TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation()); + SString strParentMethodName; + TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation()); - COMPlusThrow( - kTypeLoadException, - IDS_CLASSLOAD_MI_BADRETURNTYPE, - strInvalidMethodName, - strInvalidTypeName, - strAssemblyName, - strParentMethodName); + COMPlusThrow( + kTypeLoadException, + IDS_CLASSLOAD_MI_BADRETURNTYPE, + strInvalidMethodName, + strInvalidTypeName, + strAssemblyName, + strParentMethodName); + } } } - RETURN; + // Step 2: propate overriding MethodImpls to applicable vtable slots if the declaring method has the attribute + + for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++) + { + MethodDesc* pMD = pMT->GetMethodDescForSlot(i); + MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i); + if (pMD == pParentMD) + continue; + + // The attribute is only applicable to MethodImpls. For anything else, it will be treated as a no-op + if (!pMD->IsMethodImpl()) + continue; + + // Search if the attribute has been applied on this vtable slot, either by the current MethodImpl, or by a previous + // MethodImpl somewhere in the base type hierarchy. + bool foundAttribute = false; + MethodTable* pCurrentMT = pMT; + while (!foundAttribute && pCurrentMT != NULL && i < pCurrentMT->GetNumVirtuals()) + { + MethodDesc* pCurrentMD = pCurrentMT->GetMethodDescForSlot(i); + + // The attribute is only applicable to MethodImpls. For anything else, it will be treated as a no-op + if (pCurrentMD->IsMethodImpl()) + { + BYTE* pVal = NULL; + ULONG cbVal = 0; + if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::ValidateMethodImplRemainsInEffectAttribute, (const void**)&pVal, &cbVal) == S_OK) + foundAttribute = true; + } + + pCurrentMT = pCurrentMT->GetParentMethodTable(); + } + + if (!foundAttribute) + continue; + + // Search for any vtable slot still pointing at the parent method, and update it with the current overriding method + for (WORD j = i; j < pParentMT->GetNumVirtuals(); j++) + { + MethodDesc* pCurrentMD = pMT->GetMethodDescForSlot(j); + if (pCurrentMD == pParentMD) + { + // This is a vtable slot that needs to be updated to the new overriding method because of the + // presence of the attribute. + pMT->SetSlot(j, pMT->GetSlot(i)); + _ASSERT(pMT->GetMethodDescForSlot(j) == pMD); + } + } + } } //******************************************************************************* diff --git a/src/coreclr/src/vm/clsload.hpp b/src/coreclr/src/vm/clsload.hpp index fb569e93c7c130..c082982c886674 100644 --- a/src/coreclr/src/vm/clsload.hpp +++ b/src/coreclr/src/vm/clsload.hpp @@ -973,7 +973,7 @@ class ClassLoader static void LoadExactParentAndInterfacesTransitively(MethodTable *pMT); - static void ValidateMethodImplRemainsInEffect(MethodTable* pMT); + static void ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT); // Create a non-canonical instantiation of a generic type based off the canonical instantiation // (For example, MethodTable for List is based on the MethodTable for List<__Canon>) diff --git a/src/coreclr/src/vm/method.hpp b/src/coreclr/src/vm/method.hpp index 5973cd6d6053fc..0102f911c6dd86 100644 --- a/src/coreclr/src/vm/method.hpp +++ b/src/coreclr/src/vm/method.hpp @@ -1829,17 +1829,18 @@ class MethodDesc enum { // enum_flag2_HasPrecode implies that enum_flag2_HasStableEntryPoint is set. - enum_flag2_HasStableEntryPoint = 0x01, // The method entrypoint is stable (either precode or actual code) - enum_flag2_HasPrecode = 0x02, // Precode has been allocated for this method + enum_flag2_HasStableEntryPoint = 0x01, // The method entrypoint is stable (either precode or actual code) + enum_flag2_HasPrecode = 0x02, // Precode has been allocated for this method - enum_flag2_IsUnboxingStub = 0x04, - enum_flag2_HasNativeCodeSlot = 0x08, // Has slot for native code + enum_flag2_IsUnboxingStub = 0x04, + enum_flag2_HasNativeCodeSlot = 0x08, // Has slot for native code - enum_flag2_IsJitIntrinsic = 0x10, // Jit may expand method as an intrinsic + enum_flag2_IsJitIntrinsic = 0x10, // Jit may expand method as an intrinsic - enum_flag2_IsEligibleForTieredCompilation = 0x20, + enum_flag2_IsEligibleForTieredCompilation = 0x20, + + enum_flag2_RequiresCovariantReturnTypeChecking = 0x40 - // unused = 0x40, // unused = 0x80, }; BYTE m_bFlags2; @@ -1902,6 +1903,19 @@ class MethodDesc m_bFlags2 |= enum_flag2_IsJitIntrinsic; } + BOOL RequiresCovariantReturnTypeChecking() + { + LIMITED_METHOD_DAC_CONTRACT; + + return (m_bFlags2 & enum_flag2_RequiresCovariantReturnTypeChecking) != 0; + } + + void SetRequiresCovariantReturnTypeChecking() + { + LIMITED_METHOD_CONTRACT; + m_bFlags2 |= enum_flag2_RequiresCovariantReturnTypeChecking; + } + static const SIZE_T s_ClassificationSizeTable[]; static SIZE_T GetBaseSize(DWORD classification) diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 94db8febae35f9..ab028235c0dc2c 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -2275,6 +2275,7 @@ MethodTableBuilder::EnumerateMethodImpls() bmtMetaData->rgMethodImplTokens[i].fConsiderDuringInexactMethodImplProcessing = false; bmtMetaData->rgMethodImplTokens[i].fThrowIfUnmatchedDuringInexactMethodImplProcessing = false; bmtMetaData->rgMethodImplTokens[i].interfaceEquivalenceSet = 0; + bmtMetaData->rgMethodImplTokens[i].fRequiresCovariantReturnTypeChecking = false; if (FAILED(hr)) { @@ -2451,7 +2452,16 @@ MethodTableBuilder::EnumerateMethodImpls() if (!compatibleSignatures && IsEligibleForCovariantReturns(theDecl)) { - compatibleSignatures = MetaSig::CompareMethodSigs(pSigDecl, cbSigDecl, GetModule(), &theDeclSubst, pSigBody, cbSigBody, GetModule(), NULL, TRUE); + if (MetaSig::CompareMethodSigs(pSigDecl, cbSigDecl, GetModule(), &theDeclSubst, pSigBody, cbSigBody, GetModule(), NULL, TRUE)) + { + // Signatures matched, except for the return type. Flag that MethodImpl to check the return type at a later + // stage for compatibility, and treat it as compatible for now. + // For compatibility rules, see ECMA I.8.7.1. We will use the MethodTable::CanCastTo() at a later stage to validate + // compatibilities of the return types according to these rules. + + compatibleSignatures = TRUE; + bmtMetaData->rgMethodImplTokens[i].fRequiresCovariantReturnTypeChecking = true; + } } if (!compatibleSignatures) @@ -5621,6 +5631,11 @@ MethodTableBuilder::ProcessInexactMethodImpls() if (fPreexistingImplFound) continue; + if (bmtMetaData->rgMethodImplTokens[m].fRequiresCovariantReturnTypeChecking) + { + it->GetMethodDesc()->SetRequiresCovariantReturnTypeChecking(); + } + // Otherwise, record the method impl discovery if the match is bmtMethodImpl->AddMethodImpl(*it, declMethod, bmtMetaData->rgMethodImplTokens[m].methodDecl, GetStackingAllocator()); } @@ -5938,6 +5953,11 @@ MethodTableBuilder::ProcessMethodImpls() BuildMethodTableThrowException(IDS_CLASSLOAD_MI_MUSTBEVIRTUAL, it.Token()); } + if (bmtMetaData->rgMethodImplTokens[m].fRequiresCovariantReturnTypeChecking) + { + it->GetMethodDesc()->SetRequiresCovariantReturnTypeChecking(); + } + bmtMethodImpl->AddMethodImpl(*it, declMethod, mdDecl, GetStackingAllocator()); } } diff --git a/src/coreclr/src/vm/methodtablebuilder.h b/src/coreclr/src/vm/methodtablebuilder.h index dda4ae978ad583..b4cbcdc5ed777e 100644 --- a/src/coreclr/src/vm/methodtablebuilder.h +++ b/src/coreclr/src/vm/methodtablebuilder.h @@ -1992,6 +1992,7 @@ class MethodTableBuilder // This is to detect situations where a methodimpl does not match any method on any equivalent interface. bool fThrowIfUnmatchedDuringInexactMethodImplProcessing; UINT32 interfaceEquivalenceSet;// Equivalence set in the interface map to examine + bool fRequiresCovariantReturnTypeChecking; static int __cdecl Compare(const void *elem1, const void *elem2); static BOOL Equal(const MethodImplTokenPair *elem1, const MethodImplTokenPair *elem2); }; diff --git a/src/coreclr/src/vm/siginfo.cpp b/src/coreclr/src/vm/siginfo.cpp index dafbe670756984..1d3de2ba2107dc 100644 --- a/src/coreclr/src/vm/siginfo.cpp +++ b/src/coreclr/src/vm/siginfo.cpp @@ -3568,345 +3568,6 @@ BOOL CompareTypeTokens(mdToken tk1, mdToken tk2, Module *pModule1, Module *pModu #pragma warning(disable:21000) // Suppress PREFast warning about overly large function #endif -//--------------------------------------------------------------------------------------- -// -// Compare two type handles for equality, or that hType2 is a derived class of hType1. -// The derived type check is used by the covariant returns feature. -// -// static -BOOL MetaSig::CompareTypeHandles(TypeHandle hType1, TypeHandle hType2, BOOL allowDerivedClass) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(!hType1.IsNull() && !hType2.IsNull()); - } - CONTRACTL_END; - - if (hType1 == hType2) - return TRUE; - - if (!allowDerivedClass) - return FALSE; - - if (hType1.IsNull() || hType2.IsValueType()) - { - return FALSE; - } - - hType2 = hType2.GetParent(); - - while (!hType2.IsNull()) - { - if (hType1 == hType2) - return TRUE; - hType2 = hType2.GetParent(); - } - - return FALSE; -} - -//--------------------------------------------------------------------------------------- -// -// Check if a type signature is eligible to be used with derived type signature comparison -// and if so, return TRUE if the type is eligible. -// Inputs: -// - pSig, pEndSig, pModule : Input type signature and module to check for eligibility. -// - isBaseTypeSig : Flag indicating whether the input signature should be treated -// as that of a base type or a derived type. -// Outputs: -// - pTypeDefToken, ppTypeDefModule : TypeDef token and module of the type in the input signature -// - pParentTypeDefOrRefOrSpecToken : Base type token if the input signature is treated as -// that of a derived type. This can be a TypeDef/TypeRef/TypeSpec. -// -// static -BOOL MetaSig::IsEligibleForDerivedTypeSignatureComparison( - PCCOR_SIGNATURE pSig, - PCCOR_SIGNATURE pEndSig, - Module* pModule, - BOOL isBaseTypeSig, - mdToken* pTypeDefToken, /* = NULL */ - Module** ppTypeDefModule, /* = NULL */ - mdToken* pParentTypeDefOrRefOrSpecToken) /* = NULL */ -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - CorElementType elementType = ELEMENT_TYPE_MAX; - - IfFailThrow(CorSigUncompressElementType_EndPtr(pSig, pEndSig, &elementType)); - - // System.Object is always eligible as a base type since all reference types derive from it - if (isBaseTypeSig && elementType == ELEMENT_TYPE_OBJECT) - { - return TRUE; - } - - if (elementType == ELEMENT_TYPE_GENERICINST) - { - IfFailThrow(CorSigUncompressElementType_EndPtr(pSig, pEndSig, &elementType)); - } - - // Only classes are eligible (no inheritance with value types) - if (elementType != ELEMENT_TYPE_CLASS) - { - return FALSE; - } - - mdToken typeRefOrDefToken; - IfFailThrow(CorSigUncompressToken_EndPtr(pSig, pEndSig, &typeRefOrDefToken)); - - // Ensure we are working with the typedef token - mdToken typeDefToken; - Module* pFoundModule; - if (!ClassLoader::ResolveTokenToTypeDefThrowing(pModule, typeRefOrDefToken, &pFoundModule, &typeDefToken)) - { - return FALSE; - } - - mdToken parentTypeDefOrRefOrSpecToken = mdTokenNil; - if (!isBaseTypeSig) - { - DWORD attr; - IfFailThrow(pFoundModule->GetMDImport()->GetTypeDefProps(typeDefToken, &attr, &parentTypeDefOrRefOrSpecToken)); - - // Check the validity of the parent type token if this is a signature of a derived type. - if (!pFoundModule->GetMDImport()->IsValidToken(parentTypeDefOrRefOrSpecToken)) - { - return FALSE; - } - } - - if (ppTypeDefModule != NULL) - *ppTypeDefModule = pFoundModule; - if (pTypeDefToken != NULL) - *pTypeDefToken = typeDefToken; - if (pParentTypeDefOrRefOrSpecToken != NULL) - *pParentTypeDefOrRefOrSpecToken = parentTypeDefOrRefOrSpecToken; - - return TRUE; -} - -//--------------------------------------------------------------------------------------- -// -// Compute the base type token (it will either be a typedef or typeref token), and return the -// module where that base type token is declared. -// -// static -BOOL MetaSig::GetBaseTypeTokenAndModule( - mdToken tk, - Module* pModule, - mdToken* pBaseTypeDefOrRefToken, - Module** ppBaseTypeTokenModule) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - PRECONDITION(CheckPointer(pModule)); - PRECONDITION(CheckPointer(pBaseTypeDefOrRefToken)); - PRECONDITION(CheckPointer(ppBaseTypeTokenModule)); - PRECONDITION(TypeFromToken(tk) == mdtTypeRef || TypeFromToken(tk) == mdtTypeDef); - MODE_ANY; - } - CONTRACTL_END; - - // Ensure we are working with the typedef token - mdToken typeDefToken; - Module* pFoundModule; - if (!ClassLoader::ResolveTokenToTypeDefThrowing(pModule, tk, &pFoundModule, &typeDefToken)) - return FALSE; - - DWORD attr; - mdToken tkTypeParent; - IfFailThrow(pFoundModule->GetMDImport()->GetTypeDefProps(typeDefToken, &attr, &tkTypeParent)); - - if (!pFoundModule->GetMDImport()->IsValidToken(tkTypeParent)) - return FALSE; - - if (TypeFromToken(tkTypeParent) == mdtTypeSpec) - { - // If the base type token is a TypeSpec of a generic instantiation, extract the type definition token - - ULONG cbSig; - PCCOR_SIGNATURE pSig; - IfFailThrow(pFoundModule->GetMDImport()->GetSigFromToken(tkTypeParent, &cbSig, &pSig)); - - PCCOR_SIGNATURE pEndSig = pSig + cbSig; - CorElementType elementType = ELEMENT_TYPE_MAX; - - IfFailThrow(CorSigUncompressElementType_EndPtr(pSig, pEndSig, &elementType)); - if (elementType == ELEMENT_TYPE_GENERICINST) - { - IfFailThrow(CorSigUncompressElementType_EndPtr(pSig, pEndSig, &elementType)); - } - - if (elementType != ELEMENT_TYPE_CLASS) - return FALSE; - - IfFailThrow(CorSigUncompressToken_EndPtr(pSig, pEndSig, pBaseTypeDefOrRefToken)); - *ppBaseTypeTokenModule = pFoundModule; - - _ASSERTE(TypeFromToken(*pBaseTypeDefOrRefToken) == mdtTypeRef || TypeFromToken(*pBaseTypeDefOrRefToken) == mdtTypeDef); - _ASSERTE(pFoundModule->GetMDImport()->IsValidToken(*pBaseTypeDefOrRefToken)); - - return TRUE; - } - else if (TypeFromToken(tkTypeParent) == mdtTypeRef || TypeFromToken(tkTypeParent) == mdtTypeDef) - { - *pBaseTypeDefOrRefToken = tkTypeParent; - *ppBaseTypeTokenModule = pFoundModule; - return TRUE; - } - - return FALSE; -} - -//------------------------------------------------------------------ -// Extract the base type's signature and substitution from the second type signature -// and recompare it with the first type's signature. -//------------------------------------------------------------------ -// static -BOOL MetaSig::ComputeBaseTypeAndCompareElementType( - PCCOR_SIGNATURE & pSig1, - PCCOR_SIGNATURE & pSig2, - PCCOR_SIGNATURE pEndSig1, - PCCOR_SIGNATURE pEndSig2, - Module * pModule1, - Module * pModule2, - const Substitution * pSubst1, - const Substitution * pSubst2, - TokenPairList* pVisited) // = NULL -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - INJECT_FAULT(COMPlusThrowOM()); - MODE_ANY; - } - CONTRACTL_END; - - // Quick check of Type1 for eligibility before starting to traverse base type chain in Type2 - if (!IsEligibleForDerivedTypeSignatureComparison(pSig1, pEndSig1, pModule1, TRUE)) - { - return FALSE; - } - - // Now a quick check of Type2 for eligibility, and if eligible, compute the TypeDef module of the current type in pSig2, as well - // as the base type token (which can be a TypeRef/TypeDef/TypeSpec) - Module* pTypeDefModule; - mdToken parentTypeDefOrRefOrSpecToken; - if (!IsEligibleForDerivedTypeSignatureComparison(pSig2, pEndSig2, pModule2, FALSE, NULL, &pTypeDefModule, &parentTypeDefOrRefOrSpecToken)) - { - return FALSE; - } - - // We need to check if the signature of Type2 is that of a generic type - // and if so, insert its generic instantiation arguments to the end of the substitution chain. - // Doing so will enable type signature comparison to traverse the generic stubstitution - // chain correctly while traversing the base type hierarchy of Type2. - // The instantiation arguments substitution have to be added as the leaf node of the - // substitution chain, which is why we perform the NULL check on the substitution - - const Substitution* pCurrentSubstChain = pSubst2; - - Substitution leafSubstFromGenericArgs; - if (pSubst2 == NULL || pSubst2->GetInst().IsNull()) - { - CorElementType et; - SigParser parser(pSig2, (DWORD)(pEndSig2 - pSig2)); - IfFailThrow(parser.GetElemType(&et)); - if (et == ELEMENT_TYPE_GENERICINST) - { - IfFailThrow(parser.SkipExactlyOne()); // Skip generic type definition signature - IfFailThrow(parser.GetData(NULL)); // Skip number of generic arguments - - leafSubstFromGenericArgs = Substitution(pModule2, SigPointer(parser.GetPtr()), NULL); - - // Set the current substitution chain to the leaf node we just created. - pCurrentSubstChain = &leafSubstFromGenericArgs; - } - } - - Substitution parentTypeSubst; - SigBuilder parentTypeSigBuilder; - - // If the parent type token is a TypeSpec token, we need to load the substitution from the signature and - // chain it to the existing substitution chain. This is necessary to ensure proper comparisons - // for generic instantiation arguments while performing comparison using one of the base type's signatures. - - if (TypeFromToken(parentTypeDefOrRefOrSpecToken) == mdtTypeSpec) - { - ULONG cbParentTypeSig; - PCCOR_SIGNATURE pParentTypeSig; - IfFailThrow(pTypeDefModule->GetMDImport()->GetSigFromToken(parentTypeDefOrRefOrSpecToken, &cbParentTypeSig, &pParentTypeSig)); - - parentTypeSigBuilder.AppendSignature(pParentTypeSig, pParentTypeSig + cbParentTypeSig); - parentTypeSubst = Substitution(parentTypeDefOrRefOrSpecToken, pTypeDefModule, pCurrentSubstChain); - } - else if (TypeFromToken(parentTypeDefOrRefOrSpecToken) == mdtTypeDef || TypeFromToken(parentTypeDefOrRefOrSpecToken) == mdtTypeRef) - { - // We need to special case type System.Object since it has its own element type. We don't need to do the same for type String - // because it's a sealed type, and no other class can derive from it. Without this special casing, we'll end up with a comparison - // between a ELEMENT_TYPE_OBJECT and a ELEMENT_TYPE_CLASS respresentation of object, which we'll have to special case in the - // implementation of MetaSig::CompareElementType() by checking the type token following ELEMENT_TYPE_CLASS (possible, but adds - // unnecessary complexity). - - Module* pResolvedModule; - mdTypeDef resolvedTypeDefToken; - BOOL resolvedToken = ClassLoader::ResolveTokenToTypeDefThrowing(pTypeDefModule, parentTypeDefOrRefOrSpecToken, &pResolvedModule, &resolvedTypeDefToken); - - if (resolvedToken && pResolvedModule == g_pObjectClass->GetModule() && resolvedTypeDefToken == g_pObjectClass->GetCl()) - { - parentTypeSigBuilder.AppendElementType(ELEMENT_TYPE_OBJECT); - } - else - { - parentTypeSigBuilder.AppendElementType(ELEMENT_TYPE_CLASS); - parentTypeSigBuilder.AppendToken(parentTypeDefOrRefOrSpecToken); - } - - parentTypeSubst = (pCurrentSubstChain == NULL ? Substitution() : Substitution(*pCurrentSubstChain)); - } - else - { - return FALSE; - } - - DWORD cbParentTypeSig; - PCCOR_SIGNATURE pParentTypeSig = (PCCOR_SIGNATURE)parentTypeSigBuilder.GetSignature(&cbParentTypeSig); - PCCOR_SIGNATURE pParentTypeSigEnd = pParentTypeSig + cbParentTypeSig; - - // - // Given that we're going to restart the current type comparaison between Type1 and the base type of Type2, and - // given that the signature pointers for both types are passed by reference to get updated during each call to - // CompareElementType(), we need to skip one element from the original signature of Type2. - // - SigParser parser = SigParser(pSig2); - IfFailThrow(parser.SkipExactlyOne()); - pSig2 = parser.GetPtr(); - - return CompareElementType( - pSig1, - pParentTypeSig, - pEndSig1, - pParentTypeSigEnd, - pModule1, - pTypeDefModule, - pSubst1, - parentTypeSubst.GetInst().IsNull() ? NULL : &parentTypeSubst, - TRUE, - pVisited); -} - //--------------------------------------------------------------------------------------- // // Compare the next elements in two sigs. @@ -3922,7 +3583,6 @@ MetaSig::CompareElementType( Module * pModule2, const Substitution * pSubst1, const Substitution * pSubst2, - BOOL allowDerivedClass, TokenPairList * pVisited) // = NULL { CONTRACTL @@ -3932,10 +3592,7 @@ MetaSig::CompareElementType( INJECT_FAULT(COMPlusThrowOM()); MODE_ANY; } - CONTRACTL_END; - - PCCOR_SIGNATURE pSig1Start = pSig1; - PCCOR_SIGNATURE pSig2Start = pSig2; + CONTRACTL_END redo: // We jump here if the Type was a ET_CMOD prefix. @@ -3970,7 +3627,6 @@ MetaSig::CompareElementType( pSubst2->GetModule(), pSubst1, pSubst2->GetNext(), - allowDerivedClass, pVisited); } @@ -3998,7 +3654,6 @@ MetaSig::CompareElementType( pModule2, pSubst1->GetNext(), pSubst2, - allowDerivedClass, pVisited); } @@ -4037,21 +3692,21 @@ MetaSig::CompareElementType( { if ((Type1 == ELEMENT_TYPE_INTERNAL) || (Type2 == ELEMENT_TYPE_INTERNAL)) { - TypeHandle hType1, hType2; + TypeHandle hInternal; CorElementType eOtherType; Module * pOtherModule; // One type is already loaded, collect all the necessary information to identify the other type. if (Type1 == ELEMENT_TYPE_INTERNAL) { - IfFailThrow(CorSigUncompressPointer_EndPtr(pSig1, pEndSig1, (void **)&hType1)); + IfFailThrow(CorSigUncompressPointer_EndPtr(pSig1, pEndSig1, (void**)&hInternal)); eOtherType = Type2; pOtherModule = pModule2; } else { - IfFailThrow(CorSigUncompressPointer_EndPtr(pSig2, pEndSig2, (void **)&hType2)); + IfFailThrow(CorSigUncompressPointer_EndPtr(pSig2, pEndSig2, (void **)&hInternal)); eOtherType = Type1; pOtherModule = pModule1; @@ -4062,30 +3717,11 @@ MetaSig::CompareElementType( { case ELEMENT_TYPE_OBJECT: { - if (Type1 == ELEMENT_TYPE_INTERNAL) - { - // Type2 is ELEMENT_TYPE_OBJECT. Return true only if Type1 is also type object. - return hType1.AsMethodTable() == g_pObjectClass; - } - else - { - // Type1 is ELEMENT_TYPE_OBJECT. Return true if Type2 is type System.Object or any other class - // if allowDerivedClass is TRUE. - if (hType2.AsMethodTable() == g_pObjectClass) - { - return TRUE; - } - else - { - return allowDerivedClass ? CompareTypeHandles(TypeHandle(g_pObjectClass), hType2, TRUE) : FALSE; - } - } + return (hInternal.AsMethodTable() == g_pObjectClass); } case ELEMENT_TYPE_STRING: { - return Type1 == ELEMENT_TYPE_INTERNAL ? - hType1.AsMethodTable() == g_pStringClass : - hType2.AsMethodTable() == g_pStringClass; + return (hInternal.AsMethodTable() == g_pStringClass); } case ELEMENT_TYPE_VALUETYPE: case ELEMENT_TYPE_CLASS: @@ -4094,23 +3730,19 @@ MetaSig::CompareElementType( if (Type1 == ELEMENT_TYPE_INTERNAL) { IfFailThrow(CorSigUncompressToken_EndPtr(pSig2, pEndSig2, &tkOther)); - hType2 = ClassLoader::LoadTypeDefOrRefThrowing( - pOtherModule, - tkOther, - ClassLoader::ReturnNullIfNotFound, - ClassLoader::FailIfUninstDefOrRef); } else { IfFailThrow(CorSigUncompressToken_EndPtr(pSig1, pEndSig1, &tkOther)); - hType1 = ClassLoader::LoadTypeDefOrRefThrowing( - pOtherModule, - tkOther, - ClassLoader::ReturnNullIfNotFound, - ClassLoader::FailIfUninstDefOrRef); } - return CompareTypeHandles(hType1, hType2, allowDerivedClass); + TypeHandle hOtherType = ClassLoader::LoadTypeDefOrRefThrowing( + pOtherModule, + tkOther, + ClassLoader::ReturnNullIfNotFound, + ClassLoader::FailIfUninstDefOrRef); + + return (hInternal == hOtherType); } default: { @@ -4120,31 +3752,7 @@ MetaSig::CompareElementType( } else { - if (allowDerivedClass) - { - // Obvious case: string derives from object. - if (Type1 == ELEMENT_TYPE_OBJECT && Type2 == ELEMENT_TYPE_STRING) - { - return TRUE; - } - - // Reset pSig1 and pSig2 to their initial position (Note that their values get updated during the - // recursive calls). - pSig1 = pSig1Start; - pSig2 = pSig2Start; - return ComputeBaseTypeAndCompareElementType( - pSig1, - pSig2, - pEndSig1, - pEndSig2, - pModule1, - pModule2, - pSubst1, - pSubst2, - pVisited); - } - - return FALSE; + return FALSE; // types must be the same } } @@ -4228,7 +3836,6 @@ MetaSig::CompareElementType( pModule2, pSubst1, pSubst2, - FALSE, pVisited)) { return FALSE; @@ -4244,77 +3851,7 @@ MetaSig::CompareElementType( IfFailThrow(CorSigUncompressToken_EndPtr(pSig1, pEndSig1, &tk1)); IfFailThrow(CorSigUncompressToken_EndPtr(pSig2, pEndSig2, &tk2)); - if (CompareTypeTokens(tk1, tk2, pModule1, pModule2, pVisited)) - { - return TRUE; - } - - if (allowDerivedClass) - { - // - // We need to check if Type2 derives from Type1. Note that if Type1 is a generic type, - // we cannot check for inheritance here because we need to properly keep track of substitutions. - // - // Here's an example: - // class Class0 { } - // class Class1 : Class0 { } - // class Class2 : Class1 { } - // class Class3 : Class2 { } - // class Class4 : Class3{ } - // - // Here, we need to check if Class4 derives from Class0 - // - // In that example, if we just look at the typedef tokens for Class0 and Class4, and traverse the - // parent chain of Class4 to check if it derives from Class0, we would be always returning true, which - // is not necessarily correct all the times. - // Here's a counter example: if Class2 was declared as 'Class2 : Class1', - // then Class4 would be deriving from Class0, and not from Class0. - // - // Therefore, we need to keep track of the substitutions: - // A -> ARG1 -> T -> int32 - // B -> ARG2 -> int16 - // - // To handle that case, we need to compute the base type *AND* base type substitution chain of type2, and - // recompare that with type1. If type1 is generic, we'll return return FALSE here, so that we can properly - // handle this scenario under ELEMENT_TYPE_GENERICINST. - // - - // First, check if Type1 is eligible for covariant returns - - mdToken typeDefToken1; - Module* pTypeDefModule1; - if (!IsEligibleForDerivedTypeSignatureComparison(pSig1Start, pEndSig1, pModule1, TRUE, &typeDefToken1, &pTypeDefModule1)) - { - return FALSE; - } - - // Second, check if Type1 is generic. If so, we'll return FALSE here, and have that handled under ELEMENT_TYPE_GENERICINST - - HENUMInternal hEnumGenericPars; - IfFailThrow(pTypeDefModule1->GetMDImport()->EnumInit(mdtGenericParam, typeDefToken1, &hEnumGenericPars)); - if (pTypeDefModule1->GetMDImport()->EnumGetCount(&hEnumGenericPars) != 0) - { - return FALSE; - } - - // Finally, walk the base type chain of Type2 to check if it derives from Type1. At this point, we don't need to - // worry about generic substitutions because we know that Type1 is non-generic. A simple token-based comparison - // will yield the correct result here. - - mdToken baseType2Token = tk2; - Module* pBaseType2Module = pModule2; - while (GetBaseTypeTokenAndModule(tk2, pModule2, &baseType2Token, &pBaseType2Module) && !(baseType2Token == tk2 && pBaseType2Module == pModule2)) - { - tk2 = baseType2Token; - pModule2 = pBaseType2Module; - if (CompareTypeTokens(tk1, tk2, pModule1, pModule2, pVisited)) - { - return TRUE; - } - } - } - - return FALSE; + return CompareTypeTokens(tk1, tk2, pModule1, pModule2, pVisited); } case ELEMENT_TYPE_FNPTR: @@ -4358,7 +3895,6 @@ MetaSig::CompareElementType( pModule2, pSubst1, pSubst2, - FALSE, &newVisited)) { return FALSE; @@ -4387,28 +3923,9 @@ MetaSig::CompareElementType( pModule2, pSubst1, pSubst2, - allowDerivedClass, &newVisitedAlwaysForbidden)) { - if (!allowDerivedClass) - { - return FALSE; - } - - // Reset pSig1 and pSig2 to their initial position (Note that their values get updated during the - // recursive calls). - pSig1 = pSig1Start; - pSig2 = pSig2Start; - return ComputeBaseTypeAndCompareElementType( - pSig1, - pSig2, - pEndSig1, - pEndSig2, - pModule1, - pModule2, - pSubst1, - pSubst2, - &newVisitedAlwaysForbidden); + return FALSE; } DWORD argCnt1; @@ -4431,7 +3948,6 @@ MetaSig::CompareElementType( pModule2, pSubst1, pSubst2, - FALSE, &newVisited)) { return FALSE; @@ -4460,7 +3976,6 @@ MetaSig::CompareElementType( pModule2, pSubst1, pSubst2, - FALSE, pVisited)) { return FALSE; @@ -4541,7 +4056,7 @@ MetaSig::CompareElementType( IfFailThrow(CorSigUncompressPointer_EndPtr(pSig1, pEndSig1, (void **)&hType1)); IfFailThrow(CorSigUncompressPointer_EndPtr(pSig2, pEndSig2, (void **)&hType2)); - return CompareTypeHandles(hType1, hType2, allowDerivedClass); + return (hType1 == hType2); } } // switch // Unreachable @@ -4615,7 +4130,6 @@ MetaSig::CompareTypeDefsUnderSubstitutions( pSubst2->GetModule(), pSubst1->GetNext(), pSubst2->GetNext(), - FALSE, pVisited)) { return FALSE; @@ -4748,7 +4262,7 @@ MetaSig::CompareMethodSigs( DWORD cSig2, Module * pModule2, const Substitution * pSubst2, - BOOL allowCovariantReturn, + BOOL skipReturnTypeSig, TokenPairList * pVisited) //= NULL { CONTRACTL @@ -4843,8 +4357,20 @@ MetaSig::CompareMethodSigs( // This would be a breaking change to make this throw... see comment above _ASSERT(*pSig2 != ELEMENT_TYPE_SENTINEL); - // We are in bounds on both sides. Compare the element. - if (!CompareElementType( + if (i == 0 && skipReturnTypeSig) + { + SigPointer ptr1(pSig1, (DWORD)(pEndSig1 - pSig1)); + IfFailThrow(ptr1.SkipExactlyOne()); + pSig1 = ptr1.GetPtr(); + + SigPointer ptr2(pSig2, (DWORD)(pEndSig2 - pSig2)); + IfFailThrow(ptr2.SkipExactlyOne()); + pSig2 = ptr2.GetPtr(); + } + else + { + // We are in bounds on both sides. Compare the element. + if (!CompareElementType( pSig1, pSig2, pEndSig1, @@ -4853,10 +4379,10 @@ MetaSig::CompareMethodSigs( pModule2, pSubst1, pSubst2, - i == 0 && allowCovariantReturn, pVisited)) - { - return FALSE; + { + return FALSE; + } } } @@ -4870,7 +4396,19 @@ MetaSig::CompareMethodSigs( // do return type as well for (i = 0; i <= ArgCount1; i++) { - if (!CompareElementType( + if (i == 0 && skipReturnTypeSig) + { + SigPointer ptr1(pSig1, (DWORD)(pEndSig1 - pSig1)); + IfFailThrow(ptr1.SkipExactlyOne()); + pSig1 = ptr1.GetPtr(); + + SigPointer ptr2(pSig2, (DWORD)(pEndSig2 - pSig2)); + IfFailThrow(ptr2.SkipExactlyOne()); + pSig2 = ptr2.GetPtr(); + } + else + { + if (!CompareElementType( pSig1, pSig2, pEndSig1, @@ -4879,10 +4417,10 @@ MetaSig::CompareMethodSigs( pModule2, pSubst1, pSubst2, - i == 0 && allowCovariantReturn, pVisited)) - { - return FALSE; + { + return FALSE; + } } } @@ -4920,7 +4458,7 @@ BOOL MetaSig::CompareFieldSigs( pEndSig1 = pSig1 + cSig1; pEndSig2 = pSig2 + cSig2; - return(CompareElementType(++pSig1, ++pSig2, pEndSig1, pEndSig2, pModule1, pModule2, NULL, NULL, FALSE, pVisited)); + return(CompareElementType(++pSig1, ++pSig2, pEndSig1, pEndSig2, pModule1, pModule2, NULL, NULL, pVisited)); } #ifndef DACCESS_COMPILE @@ -5162,7 +4700,7 @@ BOOL MetaSig::CompareTypeDefOrRefOrSpec(Module *pModule1, mdToken tok1, ULONG cSig1,cSig2; IfFailThrow(pInternalImport1->GetTypeSpecFromToken(tok1, &pSig1, &cSig1)); IfFailThrow(pInternalImport2->GetTypeSpecFromToken(tok2, &pSig2, &cSig2)); - return MetaSig::CompareElementType(pSig1, pSig2, pSig1 + cSig1, pSig2 + cSig2, pModule1, pModule2, pSubst1, pSubst2, FALSE, pVisited); + return MetaSig::CompareElementType(pSig1, pSig2, pSig1 + cSig1, pSig2 + cSig2, pModule1, pModule2, pSubst1, pSubst2, pVisited); } // MetaSig::CompareTypeDefOrRefOrSpec /* static */ @@ -5747,7 +5285,6 @@ MetaSig::GetUnmanagedCallingConvention( *pPinvokeMapOut = (CorPinvokeMap)0; return TRUE; } -#endif // #ifndef DACCESS_COMPILE //--------------------------------------------------------------------------------------- // @@ -5848,6 +5385,7 @@ void Substitution::DeleteChain() delete this; } +#endif // #ifndef DACCESS_COMPILE //--------------------------------------------------------------------------------------- // // static diff --git a/src/coreclr/src/vm/siginfo.hpp b/src/coreclr/src/vm/siginfo.hpp index 08481222a53bc2..cdef8c2feb7e46 100644 --- a/src/coreclr/src/vm/siginfo.hpp +++ b/src/coreclr/src/vm/siginfo.hpp @@ -970,14 +970,6 @@ class MetaSig //------------------------------------------------------------------ CorElementType GetByRefType(TypeHandle* pTy) const; - //------------------------------------------------------------------ - // Compare two type handles for equality. If the two types are not equal, and allowDerivedClass - // is TRUE, return true if hType2 derives from hType1. This inheritance check is used to allow - // for covariant return types on MethodImpls. - //------------------------------------------------------------------ - static BOOL CompareTypeHandles(TypeHandle hType1, TypeHandle hType2, BOOL allowDerivedClass); - - //------------------------------------------------------------------ // Compare types in two signatures, first applying // - optional substitutions pSubst1 and pSubst2 @@ -992,7 +984,6 @@ class MetaSig Module * pModule2, const Substitution * pSubst1, const Substitution * pSubst2, - BOOL allowDerivedClass, TokenPairList * pVisited = NULL); @@ -1019,7 +1010,7 @@ class MetaSig DWORD cSig2, Module* pModule2, const Substitution* pSubst2, - BOOL allowCovariantReturn, + BOOL skipReturnTypeSig, TokenPairList* pVisited = NULL ); @@ -1067,53 +1058,6 @@ class MetaSig mdMethodDef tok2); //declared method private: - //------------------------------------------------------------------ - // Check if a type signature is eligible to be used with derived type signature comparisons - // and if so, return TRUE if the type is eligible. - // Inputs: - // - pSig, pEndSig, pModule : Input type signature and module to check for eligibility. - // - isBaseTypeSig : Flag indicating whether the input signature should be treated - // as that of a base type or a derived type. - // Outputs: - // - pTypeDefToken, ppTypeDefModule : TypeDef token and module of the type in the input signature - // - pParentTypeDefOrRefOrSpecToken : Base type token if the input signature is treated as - // that of a derived type. This can be a TypeDef/TypeRef/TypeSpec. - //------------------------------------------------------------------ - static BOOL IsEligibleForDerivedTypeSignatureComparison( - PCCOR_SIGNATURE pSig, - PCCOR_SIGNATURE pEndSig, - Module* pModule, - BOOL isBaseTypeSig, - mdToken* pTypeDefToken = NULL, - Module** ppTypeDefModule = NULL, - mdToken* pParentTypeDefOrRefOrSpecToken = NULL); - - //------------------------------------------------------------------ - // Compute the base type token (it will either be a typedef or typeref token), and returns the - // module where that base type token is declared. - // The input token has to either be a TypeRef or TypeDef token. - //------------------------------------------------------------------ - static BOOL GetBaseTypeTokenAndModule( - mdToken tk, - Module* pModule, - mdToken* pBaseTypeDefOrRefToken, - Module** ppBaseTypeTokenModule); - - //------------------------------------------------------------------ - // Extract the base type's signature and substitution from the second type signature - // and recompare it with the first type's signature. - //------------------------------------------------------------------ - static BOOL ComputeBaseTypeAndCompareElementType( - PCCOR_SIGNATURE & pSig1, - PCCOR_SIGNATURE & pSig2, - PCCOR_SIGNATURE pEndSig1, - PCCOR_SIGNATURE pEndSig2, - Module * pModule1, - Module * pModule2, - const Substitution * pSubst1, - const Substitution * pSubst2, - TokenPairList* pVisited = NULL); - static BOOL CompareVariableConstraints(const Substitution *pSubst1, Module *pModule1, mdGenericParam tok1, //overriding const Substitution *pSubst2, diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il deleted file mode 100644 index 52039831dbb941..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.il +++ /dev/null @@ -1,363 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -.assembly extern System.Console { } -.assembly extern mscorlib { } -.assembly InterfaceReturns { } - -.class interface public auto ansi abstract IA { } -.class interface public auto ansi abstract IB implements IA { } -.class interface public auto ansi abstract IC implements IB { } -.class interface public auto ansi abstract IGenRetType { } - -.class public auto ansi beforefieldinit Dictionary -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit GenDerive1 implements class IGenRetType -{ - .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 implements class IGenRetType -{ - .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 GenToNonGen1 implements IC -{ - .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 implements class IC -{ - .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 BaseTest -{ - .method public hidebysig newslot virtual instance object MyFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class IB MyFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class IB GenToNonGenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class IB NonGenThroughGenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class IGenRetType GenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class IGenRetType> GenFunc() - { - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test1 extends class BaseTest -{ - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride() - { - .override method instance class IB class BaseTest::NonGenThroughGenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test2 extends class BaseTest -{ - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride() - { - .override method instance class IB class BaseTest::GenToNonGenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test3 extends class BaseTest -{ - .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1() - { - .override method instance class IGenRetType class BaseTest::GenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test4 extends class BaseTest -{ - .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2() - { - .override method instance class IGenRetType> class BaseTest::GenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test5 extends class BaseTest -{ - .method public hidebysig newslot virtual instance class IGenRetType NewFunc1() - { - .override method instance object class BaseTest::MyFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test6 extends class BaseTest -{ - .method public hidebysig newslot virtual instance class IC NewFunc2() - { - .override method instance class IB class BaseTest::MyFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object -{ - .method public static void RunTest1() noinlining - { - newobj instance void class Test1::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest2() noinlining - { - newobj instance void class Test2::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest3() noinlining - { - newobj instance void class Test3::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest4() noinlining - { - newobj instance void class Test4::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest5() noinlining - { - newobj instance void class Test5::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest6() noinlining - { - newobj instance void class Test6::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public hidebysig static int32 Main( string[] args) cil managed - { - .entrypoint - .maxstack 2 - .locals init (bool V_0) - ldc.i4.1 - stloc.0 - - T1: - .try - { - call void CMain::RunTest1() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." - call void [System.Console]System.Console::WriteLine(string) - leave.s T2 - } - 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 T2 - } - - T2: - .try - { - call void CMain::RunTest2() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." - call void [System.Console]System.Console::WriteLine(string) - leave.s T3 - } - 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 T3 - } - - T3: - .try - { - call void CMain::RunTest3() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." - call void [System.Console]System.Console::WriteLine(string) - leave.s T4 - } - 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 T4 - } - - T4: - .try - { - call void CMain::RunTest4() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." - call void [System.Console]System.Console::WriteLine(string) - leave.s T5 - } - 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 T5 - } - - T5: - .try - { - call void CMain::RunTest5() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." - call void [System.Console]System.Console::WriteLine(string) - leave.s T6 - } - 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 T6 - } - - T6: - .try - { - call void CMain::RunTest6() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test6." - 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 - - ldc.i4.s 101 - ret - - PASS: - ldstr "Test PASSED" - call void [System.Console]System.Console::WriteLine(string) - ldc.i4.s 100 - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method CMain::.ctor - -} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.ilproj deleted file mode 100644 index be204aa3511097..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns.ilproj +++ /dev/null @@ -1,10 +0,0 @@ - - - Exe - BuildAndRun - 0 - - - - - diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il deleted file mode 100644 index 0871befbc6de7f..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.il +++ /dev/null @@ -1,307 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -.assembly extern System.Console { } -.assembly extern mscorlib { } -.assembly InterfaceReturns { } - -.class interface public auto ansi abstract IA { } -.class interface public auto ansi abstract IB implements IA { } -.class interface public auto ansi abstract IC implements IB { } -.class interface public auto ansi abstract IGenRetType { } - -.class public auto ansi beforefieldinit Dictionary { - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit GenDerive1 implements class IGenRetType { - .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 implements class IGenRetType { - .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 GenToNonGen1 implements IC { - .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 implements class IC { - .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 BaseTest -{ - .method public hidebysig newslot virtual instance class IGenRetType MyFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class NonGenericDerived4 GenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class GenDerive3 GenFunc() - { - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test1 extends class BaseTest -{ - .method public hidebysig newslot virtual instance class IB NonGenThroughGenOverride() - { - .override method instance class NonGenThroughGen4 class BaseTest::NonGenThroughGenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test2 extends class BaseTest -{ - .method public hidebysig newslot virtual instance class IB GenToNonGenOverride() - { - .override method instance class GenToNonGen3 class BaseTest::GenToNonGenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test3 extends class BaseTest -{ - .method public hidebysig newslot virtual instance class IGenRetType NewGenFunc1() - { - .override method instance class NonGenericDerived4 class BaseTest::GenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test4 extends class BaseTest -{ - .method public hidebysig newslot virtual instance class IGenRetType> NewGenFunc2() - { - .override method instance class GenDerive3 class BaseTest::GenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test5 extends class BaseTest -{ - .method public hidebysig newslot virtual instance object NewFunc1() - { - .override method instance class IGenRetType class BaseTest::MyFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object -{ - .method public static void RunTest1() noinlining - { - newobj instance void class Test1::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest2() noinlining - { - newobj instance void class Test2::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest3() noinlining - { - newobj instance void class Test3::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest4() noinlining - { - newobj instance void class Test4::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest5() noinlining - { - newobj instance void class Test5::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public hidebysig static int32 Main( string[] args) cil managed - { - .entrypoint - .maxstack 2 - .locals init (bool V_0) - ldc.i4.1 - stloc.0 - - T1: - .try - { - call void CMain::RunTest1() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." - call void [System.Console]System.Console::WriteLine(string) - leave.s T2 - } - 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 T2 - } - - T2: - .try - { - call void CMain::RunTest2() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." - call void [System.Console]System.Console::WriteLine(string) - leave.s T3 - } - 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 T3 - } - - T3: - .try - { - call void CMain::RunTest3() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." - call void [System.Console]System.Console::WriteLine(string) - leave.s T4 - } - 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 T4 - } - - T4: - .try - { - call void CMain::RunTest4() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." - call void [System.Console]System.Console::WriteLine(string) - leave.s T5 - } - 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 T5 - } - - T5: - .try - { - call void CMain::RunTest5() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." - 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 - - ldc.i4.s 101 - ret - - PASS: - ldstr "Test PASSED" - call void [System.Console]System.Console::WriteLine(string) - ldc.i4.s 100 - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method CMain::.ctor - -} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.ilproj deleted file mode 100644 index 3b6bc58d956513..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns2.ilproj +++ /dev/null @@ -1,10 +0,0 @@ - - - Exe - BuildAndRun - 0 - - - - - diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il deleted file mode 100644 index 870596fbcd1016..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.il +++ /dev/null @@ -1,315 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -.assembly extern System.Console { } -.assembly extern mscorlib { } -.assembly InterfaceReturns { } - -.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 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 class 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 interface public auto ansi abstract BaseTest -{ - .method public hidebysig newslot virtual instance class GenRetType MyFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class NonGenericDerived4 GenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class GenDerive3 GenFunc() - { - ldnull - ret - } -} - -.class public auto ansi beforefieldinit Test1 implements class BaseTest -{ - .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride() - { - .override method instance class NonGenThroughGen4 class BaseTest::NonGenThroughGenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test2 implements class BaseTest -{ - .method public hidebysig newslot virtual instance class B GenToNonGenOverride() - { - .override method instance class GenToNonGen3 class BaseTest::GenToNonGenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test3 implements class BaseTest -{ - .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1() - { - .override method instance class NonGenericDerived4 class BaseTest::GenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test4 implements class BaseTest -{ - .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2() - { - .override method instance class GenDerive3 class BaseTest::GenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test5 implements class BaseTest -{ - .method public hidebysig newslot virtual instance object NewFunc1() - { - .override method instance class GenRetType class BaseTest::MyFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object -{ - .method public static void RunTest1() noinlining - { - newobj instance void class Test1::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest2() noinlining - { - newobj instance void class Test2::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest3() noinlining - { - newobj instance void class Test3::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest4() noinlining - { - newobj instance void class Test4::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest5() noinlining - { - newobj instance void class Test5::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public hidebysig static int32 Main( string[] args) cil managed - { - .entrypoint - .maxstack 2 - .locals init (bool V_0) - ldc.i4.1 - stloc.0 - - T1: - .try - { - call void CMain::RunTest1() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." - call void [System.Console]System.Console::WriteLine(string) - leave.s T2 - } - 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 T2 - } - - T2: - .try - { - call void CMain::RunTest2() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." - call void [System.Console]System.Console::WriteLine(string) - leave.s T3 - } - 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 T3 - } - - T3: - .try - { - call void CMain::RunTest3() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." - call void [System.Console]System.Console::WriteLine(string) - leave.s T4 - } - 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 T4 - } - - T4: - .try - { - call void CMain::RunTest4() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." - call void [System.Console]System.Console::WriteLine(string) - leave.s T5 - } - 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 T5 - } - - T5: - .try - { - call void CMain::RunTest5() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." - 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 - - ldc.i4.s 101 - ret - - PASS: - ldstr "Test PASSED" - call void [System.Console]System.Console::WriteLine(string) - ldc.i4.s 100 - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method CMain::.ctor - -} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.ilproj deleted file mode 100644 index 01bdabf789e477..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns3.ilproj +++ /dev/null @@ -1,10 +0,0 @@ - - - Exe - BuildAndRun - 0 - - - - - diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il deleted file mode 100644 index 8cb51738d8a734..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.il +++ /dev/null @@ -1,316 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -.assembly extern System.Console { } -.assembly extern System.Runtime { } -.assembly extern mscorlib { } -.assembly InterfaceReturns { } - -.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 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 class 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 interface public auto ansi abstract BaseTest -{ - .method public hidebysig newslot virtual instance class GenRetType MyFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class NonGenericDerived4 GenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class GenDerive3 GenFunc() - { - ldnull - ret - } -} - -.class interface public auto ansi abstract Test1 implements class BaseTest -{ - .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride() - { - .override method instance class NonGenThroughGen4 class BaseTest::NonGenThroughGenFunc() - ldnull - ret - } -} - -.class interface public auto ansi abstract Test2 implements class BaseTest -{ - .method public hidebysig newslot virtual instance class B GenToNonGenOverride() - { - .override method instance class GenToNonGen3 class BaseTest::GenToNonGenFunc() - ldnull - ret - } -} - -.class interface public auto ansi abstract Test3 implements class BaseTest -{ - .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1() - { - .override method instance class NonGenericDerived4 class BaseTest::GenFunc() - ldnull - ret - } -} - -.class interface public auto ansi abstract Test4 implements class BaseTest -{ - .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2() - { - .override method instance class GenDerive3 class BaseTest::GenFunc() - ldnull - ret - } -} - -.class interface public auto ansi abstract Test5 implements class BaseTest -{ - .method public hidebysig newslot virtual instance object NewFunc1() - { - .override method instance class GenRetType class BaseTest::MyFunc() - ldnull - ret - } -} - -.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object -{ - .method public static void RunTest1() noinlining - { - ldtoken class Test1 - call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest2() noinlining - { - ldtoken class Test2 - call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest3() noinlining - { - ldtoken class Test3 - call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest4() noinlining - { - ldtoken class Test4 - call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest5() noinlining - { - ldtoken class Test5 - call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public hidebysig static int32 Main( string[] args) cil managed - { - .entrypoint - .maxstack 2 - .locals init (bool V_0) - ldc.i4.1 - stloc.0 - - T1: - .try - { - call void CMain::RunTest1() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." - call void [System.Console]System.Console::WriteLine(string) - leave.s T2 - } - 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 T2 - } - - T2: - .try - { - call void CMain::RunTest2() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." - call void [System.Console]System.Console::WriteLine(string) - leave.s T3 - } - 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 T3 - } - - T3: - .try - { - call void CMain::RunTest3() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." - call void [System.Console]System.Console::WriteLine(string) - leave.s T4 - } - 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 T4 - } - - T4: - .try - { - call void CMain::RunTest4() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." - call void [System.Console]System.Console::WriteLine(string) - leave.s T5 - } - 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 T5 - } - - T5: - .try - { - call void CMain::RunTest5() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." - 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 - - ldc.i4.s 101 - ret - - PASS: - ldstr "Test PASSED" - call void [System.Console]System.Console::WriteLine(string) - ldc.i4.s 100 - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method CMain::.ctor - -} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.ilproj deleted file mode 100644 index a514e3ab598aa2..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/InterfaceReturns/InterfaceReturns4.ilproj +++ /dev/null @@ -1,10 +0,0 @@ - - - Exe - BuildAndRun - 0 - - - - - diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/ImplicitOverrideSameSigAsDecl.il similarity index 52% rename from src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il rename to src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/ImplicitOverrideSameSigAsDecl.il index d0d62a5df0952e..09ed573cf8b59c 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/ImplicitOverrideSameSigAsDecl.il @@ -6,100 +6,83 @@ .assembly extern System.Private.CoreLib { } .assembly extern System.Runtime { } .assembly extern mscorlib { } -.assembly IncompatibleReturnNoValidation { } +.assembly ImplicitOverrideSameSigAsDecl { } -.class public auto ansi beforefieldinit A -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +// ======================================================================================== +// 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 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 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 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 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 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 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 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 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 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 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 NonGenericDerived4 extends NonGenericDerived3 { + .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 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 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 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 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 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 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 NonGenThroughGen4 extends NonGenThroughGen3 { + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } +// ======================================================================================== +// Main base type with various virtual methods that will be overriden later +// ======================================================================================== + .class public auto ansi beforefieldinit GenBaseType { - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .method public hidebysig newslot virtual instance object MyFunc(string& res) { @@ -149,17 +132,11 @@ newobj instance void class GenRetType>::.ctor() ret } - .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) - { - ldarg.1 - ldstr "GenRetType GenBaseType.TestNonGenericDerived()" - stind.ref - newobj instance void class GenRetType::.ctor() - ret - } } - +// ======================================================================================== +// SECOND LAYER type: overrides all virtuals on GenBaseType using MethodImpls with +// covariant return types (more derived return types) // ======================================================================================== .class public auto ansi beforefieldinit GenTestType extends class GenBaseType @@ -224,172 +201,112 @@ ret } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenBaseType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } // ======================================================================================== - -// ======================================================================================== -// The following types are overriding base type methods that have already been overridden -// with covariant return types, but the return type here is not compatible (return type is -// a base type of the covariant return type of existing overrides). Validation is only -// triggered by the presence of the ValidateMethodImplRemainsInEffect attribute, so the -// following types should successfully load since they do not have the attribute. +// THIRD LAYER INVALID types: implicitly override the virtual methods on GenBaseType, using +// the same signature as GenBaseType, and are expected to throw TypeLoadExceptions on load +// because the return types here are not compatible with the return types used on GenTestType // ======================================================================================== -.class public auto ansi beforefieldinit IncompatibleButValid1 extends class GenTestType + +.class public auto ansi beforefieldinit Invalid1 extends class GenTestType { - .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride_IncompatibleButValid(string& res) + .method public hidebysig virtual instance object MyFunc(string& res) { - .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldnull ret } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } - -.class public auto ansi beforefieldinit IncompatibleButValid2 extends class GenTestType +.class public auto ansi beforefieldinit Invalid2 extends class GenTestType { - .method public hidebysig newslot virtual instance class B GenToNonGenOverride_IncompatibleButValid(string& res) + .method public hidebysig virtual instance class B MyFunc(string& res) { - .override method instance class B class GenBaseType::GenToNonGen(string& res) ldnull ret } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } - -.class public auto ansi beforefieldinit IncompatibleButValid3 extends class GenTestType +.class public auto ansi beforefieldinit Invalid3 extends class GenTestType { - .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1_IncompatibleButValid(string& res) + .method public hidebysig virtual instance class B GenToNonGen(string& res) { - .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldnull ret } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } - -.class public auto ansi beforefieldinit IncompatibleButValid4 extends class GenTestType +.class public auto ansi beforefieldinit Invalid4 extends class GenTestType { - .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2_IncompatibleButValid(string& res) + .method public hidebysig virtual instance class B NonGenThroughGenFunc(string& res) { - .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldnull ret } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } - -.class public auto ansi beforefieldinit IncompatibleButValid5 extends class GenTestType +.class public auto ansi beforefieldinit Invalid5 extends class GenTestType { - .method public hidebysig newslot virtual instance object NewFunc1_IncompatibleButValid(string& res) + .method public hidebysig virtual instance class GenRetType MyGenFunc(string& res) { - .override method instance object class GenBaseType::MyFunc(string& res) ldnull ret } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } - -.class public auto ansi beforefieldinit IncompatibleButValid6 extends class GenTestType +.class public auto ansi beforefieldinit Invalid6 extends class GenTestType { - .method public hidebysig newslot virtual instance class B NewFunc2_IncompatibleButValid(string& res) + .method public hidebysig virtual instance class GenRetType> MyGenFunc(string& res) { - .override method instance class B class GenBaseType::MyFunc(string& res) ldnull ret } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } +// ======================================================================================== + .class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object { .method public static void RunTest1() noinlining { - newobj instance void class IncompatibleButValid1::.ctor() + newobj instance void class Invalid1::.ctor() call void [System.Console]System.Console::WriteLine(object) ret } .method public static void RunTest2() noinlining { - newobj instance void class IncompatibleButValid2::.ctor() + newobj instance void class Invalid2::.ctor() call void [System.Console]System.Console::WriteLine(object) ret } .method public static void RunTest3() noinlining { - newobj instance void class IncompatibleButValid3::.ctor() + newobj instance void class Invalid3::.ctor() call void [System.Console]System.Console::WriteLine(object) ret } .method public static void RunTest4() noinlining { - newobj instance void class IncompatibleButValid4::.ctor() + newobj instance void class Invalid4::.ctor() call void [System.Console]System.Console::WriteLine(object) ret } .method public static void RunTest5() noinlining { - newobj instance void class IncompatibleButValid5::.ctor() + newobj instance void class Invalid5::.ctor() call void [System.Console]System.Console::WriteLine(object) ret } .method public static void RunTest6() noinlining { - newobj instance void class IncompatibleButValid6::.ctor() + newobj instance void class Invalid6::.ctor() call void [System.Console]System.Console::WriteLine(object) ret } @@ -398,15 +315,127 @@ { .entrypoint .maxstack 2 - - // No exception should be thrown here. - call void CMain::RunTest1() - call void CMain::RunTest2() - call void CMain::RunTest3() - call void CMain::RunTest4() - call void CMain::RunTest5() - call void CMain::RunTest6() - + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + 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 T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + 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 T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + 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 T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + 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 T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid5." + call void [System.Console]System.Console::WriteLine(string) + leave.s T6 + } + 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 T6 + } + + T6: + .try + { + call void CMain::RunTest6() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid6." + 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 + + ldc.i4.s 101 + ret + + PASS: ldstr "Test PASSED" call void [System.Console]System.Console::WriteLine(string) ldc.i4.s 100 diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/ImplicitOverrideSameSigAsDecl.ilproj similarity index 100% rename from src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.ilproj rename to src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/ImplicitOverrideSameSigAsDecl.ilproj diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/OverrideSameSigAsDecl.il similarity index 89% rename from src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il rename to src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/OverrideSameSigAsDecl.il index 2c8a0cb50aebf5..16b8da89179207 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/OverrideSameSigAsDecl.il @@ -8,6 +8,10 @@ .assembly extern mscorlib { } .assembly OverrideSameSigAsDecl { } +// ======================================================================================== +// 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 } } @@ -72,15 +76,13 @@ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } +// ======================================================================================== +// Main base type with various virtual methods that will be overriden later +// ======================================================================================== + .class public auto ansi beforefieldinit GenBaseType { - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .method public hidebysig newslot virtual instance object MyFunc(string& res) { @@ -141,6 +143,9 @@ } +// ======================================================================================== +// SECOND LAYER type: overrides all virtuals on GenBaseType using MethodImpls with +// covariant return types (more derived return types) // ======================================================================================== .class public auto ansi beforefieldinit GenTestType extends class GenBaseType @@ -214,122 +219,86 @@ } } +// ======================================================================================== +// THIRD LAYER INVALID types: explicitly override the virtual methods on GenBaseType, using +// the same signature as GenBaseType, and are expected to throw TypeLoadExceptions on load +// because the return types here are not compatible with the return types used on GenTestType // ======================================================================================== .class public auto ansi beforefieldinit Invalid1 extends class GenTestType { .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride_Invalid(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldnull ret } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Invalid2 extends class GenTestType { .method public hidebysig newslot virtual instance class B GenToNonGenOverride_Invalid(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldnull ret } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Invalid3 extends class GenTestType { .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1_Invalid(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldnull ret } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Invalid4 extends class GenTestType { .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2_Invalid(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldnull ret } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Invalid5 extends class GenTestType { .method public hidebysig newslot virtual instance object NewFunc1_Invalid(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance object class GenBaseType::MyFunc(string& res) ldnull ret } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } .class public auto ansi beforefieldinit Invalid6 extends class GenTestType { .method public hidebysig newslot virtual instance class B NewFunc2_Invalid(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc(string& res) ldnull ret } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } +// ======================================================================================== + .class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object { .method public static void RunTest1() noinlining diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/OverrideSameSigAsDecl.ilproj similarity index 100% rename from src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/OverrideSameSigAsDecl.ilproj rename to src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/OverrideSameSigAsDecl.ilproj diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il deleted file mode 100644 index f1bb9d3f53c973..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.il +++ /dev/null @@ -1,338 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -.assembly extern System.Console { } -.assembly extern mscorlib { } -.assembly StructReturns { } - -.class public sealed auto ansi A extends [mscorlib]System.ValueType { } -.class public sealed auto ansi GenStruct extends [mscorlib]System.ValueType { } - - -.class public auto ansi C -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public auto ansi 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 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 class 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 BaseType -{ - .method public hidebysig newslot virtual instance valuetype A MyFunc() - { - .locals ( [0] valuetype A ) - ldloc.0 - ret - } - .method public hidebysig newslot virtual instance valuetype A GenToNonGen() - { - .locals ( [0] valuetype A ) - ldloc.0 - ret - } - .method public hidebysig newslot virtual instance valuetype A NonGenThroughGenFunc() - { - .locals ( [0] valuetype A ) - ldloc.0 - ret - } - .method public hidebysig newslot virtual instance valuetype GenStruct MyGenFunc() - { - .locals ( [0] valuetype GenStruct ) - ldloc.0 - ret - } - .method public hidebysig newslot virtual instance valuetype GenStruct> MyGenFunc() - { - .locals ( [0] valuetype GenStruct> ) - ldloc.0 - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test1 extends class BaseType -{ - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride() - { - .override method instance valuetype A class BaseType::NonGenThroughGenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test2 extends class BaseType -{ - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride() - { - .override method instance valuetype A class BaseType::GenToNonGen() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test3 extends class BaseType -{ - .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1() - { - .override method instance valuetype GenStruct class BaseType::MyGenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test4 extends class BaseType -{ - .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc1() - { - .override method instance valuetype GenStruct> class BaseType::MyGenFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test5 extends class BaseType -{ - .method public hidebysig newslot virtual instance class C NewFunc2() - { - .override method instance valuetype A class BaseType::MyFunc() - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - - - -.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object -{ - .method public static void RunTest1() noinlining - { - newobj instance void class Test1::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest2() noinlining - { - newobj instance void class Test2::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest3() noinlining - { - newobj instance void class Test3::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest4() noinlining - { - newobj instance void class Test4::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest5() noinlining - { - newobj instance void class Test5::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public hidebysig static int32 Main( string[] args) cil managed - { - .entrypoint - .maxstack 2 - .locals init (bool V_0) - ldc.i4.1 - stloc.0 - - T1: - .try - { - call void CMain::RunTest1() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." - call void [System.Console]System.Console::WriteLine(string) - leave.s T2 - } - 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 T2 - } - - T2: - .try - { - call void CMain::RunTest2() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." - call void [System.Console]System.Console::WriteLine(string) - leave.s T3 - } - 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 T3 - } - - T3: - .try - { - call void CMain::RunTest3() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." - call void [System.Console]System.Console::WriteLine(string) - leave.s T4 - } - 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 T4 - } - - T4: - .try - { - call void CMain::RunTest4() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." - call void [System.Console]System.Console::WriteLine(string) - leave.s T5 - } - 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 T5 - } - - T5: - .try - { - call void CMain::RunTest5() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." - 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 - - ldc.i4.s 101 - ret - - PASS: - ldstr "Test PASSED" - call void [System.Console]System.Console::WriteLine(string) - ldc.i4.s 100 - ret - } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method CMain::.ctor - -} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il deleted file mode 100644 index 1a76008e24b275..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.il +++ /dev/null @@ -1,338 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -.assembly extern System.Console { } -.assembly extern mscorlib { } -.assembly StructReturns { } - -.class public sealed auto ansi A extends [mscorlib]System.ValueType { } -.class public sealed auto ansi GenStruct extends [mscorlib]System.ValueType { } - - -.class public auto ansi C -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public auto ansi 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 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 class 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 BaseType -{ - .method public hidebysig newslot virtual instance class C MyFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGen() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class NonGenericDerived4 MyGenFunc() - { - ldnull - ret - } - .method public hidebysig newslot virtual instance class GenDerive3 MyGenFunc() - { - ldnull - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test1 extends class BaseType -{ - .method public hidebysig newslot virtual instance valuetype A NonGenThroughGenOverride() - { - .override method instance class NonGenThroughGen4 class BaseType::NonGenThroughGenFunc() - .locals ( [0] valuetype A ) - ldloc.0 - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test2 extends class BaseType -{ - .method public hidebysig newslot virtual instance valuetype A GenToNonGenOverride() - { - .override method instance class GenToNonGen3 class BaseType::GenToNonGen() - .locals ( [0] valuetype A ) - ldloc.0 - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test3 extends class BaseType -{ - .method public hidebysig newslot virtual instance valuetype GenStruct NewGenFunc1() - { - .override method instance class NonGenericDerived4 class BaseType::MyGenFunc() - .locals ( [0] valuetype GenStruct ) - ldloc.0 - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test4 extends class BaseType -{ - .method public hidebysig newslot virtual instance valuetype GenStruct> NewGenFunc1() - { - .override method instance class GenDerive3 class BaseType::MyGenFunc() - .locals ( [0] valuetype GenStruct> ) - ldloc.0 - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -.class public auto ansi beforefieldinit Test5 extends class BaseType -{ - .method public hidebysig newslot virtual instance valuetype A NewFunc2() - { - .override method instance class C class BaseType::MyFunc() - .locals ( [0] valuetype A ) - ldloc.0 - ret - } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - - - -.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object -{ - .method public static void RunTest1() noinlining - { - newobj instance void class Test1::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest2() noinlining - { - newobj instance void class Test2::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest3() noinlining - { - newobj instance void class Test3::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest4() noinlining - { - newobj instance void class Test4::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public static void RunTest5() noinlining - { - newobj instance void class Test5::.ctor() - call void [System.Console]System.Console::WriteLine(object) - ret - } - - .method public hidebysig static int32 Main( string[] args) cil managed - { - .entrypoint - .maxstack 2 - .locals init (bool V_0) - ldc.i4.1 - stloc.0 - - T1: - .try - { - call void CMain::RunTest1() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." - call void [System.Console]System.Console::WriteLine(string) - leave.s T2 - } - 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 T2 - } - - T2: - .try - { - call void CMain::RunTest2() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." - call void [System.Console]System.Console::WriteLine(string) - leave.s T3 - } - 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 T3 - } - - T3: - .try - { - call void CMain::RunTest3() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." - call void [System.Console]System.Console::WriteLine(string) - leave.s T4 - } - 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 T4 - } - - T4: - .try - { - call void CMain::RunTest4() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." - call void [System.Console]System.Console::WriteLine(string) - leave.s T5 - } - 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 T5 - } - - T5: - .try - { - call void CMain::RunTest5() - ldc.i4.0 - stloc.0 - ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." - 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 - - ldc.i4.s 101 - ret - - PASS: - ldstr "Test PASSED" - call void [System.Console]System.Console::WriteLine(string) - ldc.i4.s 100 - ret - } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method CMain::.ctor - -} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.ilproj deleted file mode 100644 index 6219c833c18cab..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns2.ilproj +++ /dev/null @@ -1,10 +0,0 @@ - - - Exe - BuildAndRun - 0 - - - - - diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il new file mode 100644 index 00000000000000..fcdb89f5ac67de --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il @@ -0,0 +1,1281 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// This test validates the behavior in the presence/absence of the ValidateMethodImplRemainsInEffectAttribute. +// 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 +// + +.assembly extern System.Console { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly AttributeTesting { } + + +// 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 [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.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 [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.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 [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.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 [System.Runtime]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 [System.Runtime]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 [System.Runtime]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( string[] args) 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 + } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.ilproj similarity index 83% rename from src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.ilproj rename to src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.ilproj index c04e576a800da2..4fb61666a1e57e 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/StructReturns/StructReturns.ilproj +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.ilproj @@ -5,6 +5,6 @@ 0 - + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il index df158c81ce452e..8450a1e6c7bed6 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il @@ -7,6 +7,10 @@ .assembly extern mscorlib { } .assembly ReOverrideMoreDerivedReturn { } +// ======================================================================================== +// 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 } @@ -32,6 +36,10 @@ { .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } +.class public auto ansi beforefieldinit GenDerivedRetType2 extends class GenDerivedRetType +{ + .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 } @@ -114,15 +122,13 @@ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } +// ======================================================================================== +// Main base type with various virtual methods that will be overriden later +// ======================================================================================== + .class public auto ansi beforefieldinit GenBaseType { - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .method public hidebysig newslot virtual instance object MyFunc(string& res) { @@ -183,11 +189,14 @@ } +// ======================================================================================== +// SECOND LAYER type: overrides all virtuals on GenBaseType using MethodImpls with +// covariant return types (more derived return types) // ======================================================================================== .class public auto ansi beforefieldinit GenTestType extends class GenBaseType { - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc(string& res) { .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldarg.1 @@ -197,71 +206,69 @@ ret } - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGen(string& res) { .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 - ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + ldstr "GenToNonGen3 TestType.GenToNonGen()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + .method public hidebysig newslot virtual instance class NonGenericDerived4 MyGenFunc(string& res) { .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 - ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + ldstr "NonGenericDerived4 TestType.MyGenFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + .method public hidebysig newslot virtual instance class GenDerive3 MyGenFunc(string& res) { .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 - ldstr "GenDerive3 TestType.NewGenFunc2()" + ldstr "GenDerive3 TestType.MyGenFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class GenDerivedRetType NewFunc1(string& res) + .method public hidebysig newslot virtual instance class GenDerivedRetType MyFunc(string& res) { .override method instance object class GenBaseType::MyFunc(string& res) ldarg.1 - ldstr "GenDerivedRetType TestType.NewFunc1()" + ldstr "GenDerivedRetType TestType.MyFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + .method public hidebysig newslot virtual instance class C MyFunc(string& res) { .override method instance class B class GenBaseType::MyFunc(string& res) ldarg.1 - ldstr "C TestType.NewFunc2()" + ldstr "C TestType.MyFunc()" stind.ref ldnull ret } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenBaseType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } +// ======================================================================================== +// THIRD LAYER types: explicitly override the virtual methods on GenBaseType, using +// more derived return types than the ones in the MethodImpls on GenTestType // ======================================================================================== .class public auto ansi beforefieldinit GenDerivedTestType extends class GenTestType { - .method public hidebysig newslot virtual instance class NonGenThroughGen5 NonGenThroughGenOverride(string& res) + .method public hidebysig newslot virtual instance class NonGenThroughGen5 NonGenThroughGenFunc(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldarg.1 ldstr "NonGenThroughGen5 DerivedTestType.NonGenThroughGenFunc()" @@ -270,206 +277,339 @@ ret } - .method public hidebysig newslot virtual instance class GenToNonGen4 GenToNonGenOverride(string& res) + .method public hidebysig newslot virtual instance class GenToNonGen4 GenToNonGen(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 - ldstr "GenToNonGen4 DerivedTestType.GenToNonGenOverride()" + ldstr "GenToNonGen4 DerivedTestType.GenToNonGen()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class NonGenericDerived5 NewGenFunc1(string& res) + .method public hidebysig newslot virtual instance class NonGenericDerived5 MyGenFunc(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 - ldstr "NonGenericDerived5 DerivedTestType.NewGenFunc1()" + ldstr "NonGenericDerived5 DerivedTestType.MyGenFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class GenDerive4 NewGenFunc2(string& res) + .method public hidebysig newslot virtual instance class GenDerive4 MyGenFunc(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 - ldstr "GenDerive4 DerivedTestType.NewGenFunc2()" + ldstr "GenDerive4 DerivedTestType.MyGenFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class GenDerivedRetType NewFunc1(string& res) + .method public hidebysig newslot virtual instance class GenDerivedRetType2 MyFunc(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance object class GenBaseType::MyFunc(string& res) ldarg.1 - ldstr "GenDerivedRetType DerivedTestType.NewFunc1()" + ldstr "GenDerivedRetType2 DerivedTestType.MyFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class D NewFunc2(string& res) + .method public hidebysig newslot virtual instance class D MyFunc(string& res) { + .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc(string& res) ldarg.1 - ldstr "D DerivedTestType.NewFunc2()" + ldstr "D DerivedTestType.MyFunc()" stind.ref ldnull ret } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - 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 GenDerivedTestType ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenTestType with covariant returns + // 3) The signature from GenDerivedTestType with covariant returns + // And verify that the override on GenDerivedTestType is the one that executes + .method public static bool RunTest1() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenDerivedRetType DerivedTestType.NewFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenDerivedTestType::.ctor() ldloca.s 0 callvirt instance object class GenBaseType::MyFunc(string&) pop - + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 1 + callvirt instance class GenDerivedRetType class GenTestType::MyFunc(string&) + pop + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 2 + callvirt instance class GenDerivedRetType2 class GenDerivedTestType::MyFunc(string&) + pop + + ldstr "GenDerivedRetType2 DerivedTestType.MyFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenDerivedRetType DerivedTestType.NewFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest2() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: D DerivedTestType.NewFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenDerivedTestType::.ctor() ldloca.s 0 callvirt instance class B class GenBaseType::MyFunc(string&) pop - + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 1 + callvirt instance class C class GenTestType::MyFunc(string&) + pop + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 2 + callvirt instance class D class GenDerivedTestType::MyFunc(string&) + pop + + ldstr "D DerivedTestType.MyFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "D DerivedTestType.NewFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest3() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenDerive4 DerivedTestType.NewGenFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenDerivedTestType::.ctor() ldloca.s 0 callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) pop - + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 1 + callvirt instance class GenDerive3 class GenTestType::MyGenFunc(string&) + pop + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 2 + callvirt instance class GenDerive4 class GenDerivedTestType::MyGenFunc(string&) + pop + + ldstr "GenDerive4 DerivedTestType.MyGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenDerive4 DerivedTestType.NewGenFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest4() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenericDerived5 DerivedTestType.NewGenFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenDerivedTestType::.ctor() ldloca.s 0 callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) pop - + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 1 + callvirt instance class NonGenericDerived4 class GenTestType::MyGenFunc(string&) + pop + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 2 + callvirt instance class NonGenericDerived5 class GenDerivedTestType::MyGenFunc(string&) + pop + + ldstr "NonGenericDerived5 DerivedTestType.MyGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenericDerived5 DerivedTestType.NewGenFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest5() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenToNonGen4 DerivedTestType.GenToNonGenOverride()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenDerivedTestType::.ctor() ldloca.s 0 callvirt instance class B class GenBaseType::GenToNonGen(string&) pop - + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 1 + callvirt instance class GenToNonGen3 class GenTestType::GenToNonGen(string&) + pop + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 2 + callvirt instance class GenToNonGen4 class GenDerivedTestType::GenToNonGen(string&) + pop + + ldstr "GenToNonGen4 DerivedTestType.GenToNonGen()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenToNonGen4 DerivedTestType.GenToNonGenOverride()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest6() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenThroughGen5 DerivedTestType.NonGenThroughGenFunc()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenDerivedTestType::.ctor() ldloca.s 0 - callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string&) pop - + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 1 + callvirt instance class NonGenThroughGen4 class GenTestType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class GenDerivedTestType::.ctor() + ldloca.s 2 + callvirt instance class NonGenThroughGen5 class GenDerivedTestType::NonGenThroughGenFunc(string&) + pop + + ldstr "NonGenThroughGen5 DerivedTestType.NonGenThroughGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenThroughGen5 DerivedTestType.NonGenThroughGenFunc()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } + // ===================================================================================== // + .method public hidebysig static int32 Main( string[] args) cil managed { .entrypoint diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il deleted file mode 100644 index d90b4c0617a0c5..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.il +++ /dev/null @@ -1,519 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -.assembly extern System.Console { } -.assembly extern System.Runtime { } -.assembly extern mscorlib { } -.assembly ReOverrideSameReturn { } - -.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 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 GenBaseType -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - 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 - } - .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) - { - ldarg.1 - ldstr "GenRetType GenBaseType.TestNonGenericDerived()" - stind.ref - newobj instance void class GenRetType::.ctor() - ret - } -} - - -// ======================================================================================== - -.class public auto ansi beforefieldinit GenTestType extends class GenBaseType -{ - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) - { - .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) - ldarg.1 - ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) - { - .override method instance class B class GenBaseType::GenToNonGen(string& res) - ldarg.1 - ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) - { - .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) - ldarg.1 - ldstr "NonGenericDerived4 TestType.NewGenFunc1()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) - { - .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) - ldarg.1 - ldstr "GenDerive3 TestType.NewGenFunc2()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) - { - .override method instance object class GenBaseType::MyFunc(string& res) - ldarg.1 - ldstr "GenRetType TestType.NewFunc1()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class C NewFunc2(string& res) - { - .override method instance class B class GenBaseType::MyFunc(string& res) - ldarg.1 - ldstr "C TestType.NewFunc2()" - stind.ref - ldnull - ret - } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenBaseType::.ctor() - ret - } -} - -// ======================================================================================== - -.class public auto ansi beforefieldinit GenDerivedTestType extends class GenTestType -{ - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) - { - .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) - ldarg.1 - ldstr "NonGenThroughGen4 DerivedTestType.NonGenThroughGenFunc()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) - { - .override method instance class B class GenBaseType::GenToNonGen(string& res) - ldarg.1 - ldstr "GenToNonGen3 DerivedTestType.GenToNonGenOverride()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) - { - .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) - ldarg.1 - ldstr "NonGenericDerived4 DerivedTestType.NewGenFunc1()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) - { - .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) - ldarg.1 - ldstr "GenDerive3 DerivedTestType.NewGenFunc2()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) - { - .override method instance object class GenBaseType::MyFunc(string& res) - ldarg.1 - ldstr "GenRetType DerivedTestType.NewFunc1()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class C NewFunc2(string& res) - { - .override method instance class B class GenBaseType::MyFunc(string& res) - ldarg.1 - ldstr "C DerivedTestType.NewFunc2()" - stind.ref - ldnull - ret - } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenTestType::.ctor() - ret - } -} - -.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object -{ - .method public static bool RunTest1() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenRetType DerivedTestType.NewFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenDerivedTestType::.ctor() - ldloca.s 0 - callvirt instance object class GenBaseType::MyFunc(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenRetType DerivedTestType.NewFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest2() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: C DerivedTestType.NewFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenDerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class B class GenBaseType::MyFunc(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "C DerivedTestType.NewFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest3() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenDerive3 DerivedTestType.NewGenFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenDerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenDerive3 DerivedTestType.NewGenFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest4() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenericDerived4 DerivedTestType.NewGenFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenDerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenericDerived4 DerivedTestType.NewGenFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest5() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenToNonGen3 DerivedTestType.GenToNonGenOverride()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenDerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class B class GenBaseType::GenToNonGen(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenToNonGen3 DerivedTestType.GenToNonGenOverride()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest6() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenThroughGen4 DerivedTestType.NonGenThroughGenFunc()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenDerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenThroughGen4 DerivedTestType.NonGenThroughGenFunc()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public hidebysig static int32 Main( string[] args) cil managed - { - .entrypoint - .maxstack 2 - .locals init ( bool result ) - - ldc.i4.1 - stloc.0 - - T1: - call bool CMain::RunTest1() - brtrue.s T2 - ldc.i4.0 - stloc.0 - - T2: - call bool CMain::RunTest2() - brtrue.s T3 - ldc.i4.0 - stloc.0 - - T3: - call bool CMain::RunTest3() - brtrue.s T4 - ldc.i4.0 - stloc.0 - - T4: - call bool CMain::RunTest4() - brtrue.s T5 - ldc.i4.0 - stloc.0 - - T5: - call bool CMain::RunTest5() - brtrue.s T6 - ldc.i4.0 - stloc.0 - - T6: - call bool CMain::RunTest6() - brtrue.s DONE - ldc.i4.0 - 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 - } -} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.ilproj deleted file mode 100644 index 170f887ed88f0e..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideSameReturn.ilproj +++ /dev/null @@ -1,10 +0,0 @@ - - - Exe - BuildAndRun - 0 - - - - - diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il index 21f3108701e9b9..e124ae2f896760 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il @@ -8,6 +8,10 @@ .assembly extern mscorlib { } .assembly UnitTest { } +// ======================================================================================== +// 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 } @@ -91,15 +95,14 @@ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } + +// ======================================================================================== +// Main base type with various virtual methods that will be overriden later +// ======================================================================================== + .class public auto ansi beforefieldinit GenBaseType { - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .method public hidebysig newslot virtual instance object MyFunc(string& res) { @@ -149,30 +152,18 @@ newobj instance void class GenRetType>::.ctor() ret } - .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) - { - ldarg.1 - ldstr "GenRetType GenBaseType.TestNonGenericDerived()" - 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 - { - .maxstack 8 - ldarg.0 - call instance void class GenBaseType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } - .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenOverride_Middle(string& res) + .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenFunc(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) @@ -183,34 +174,34 @@ ret } - .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGenOverride_Middle(string& res) + .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGen(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 - ldstr "GenToNonGen1> GenMiddleType.GenToNonGenOverride()" + ldstr "GenToNonGen1> GenMiddleType.GenToNonGen()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class NonGenericDerived1 NewGenFunc1_Middle(string& res) + .method public hidebysig newslot virtual instance class NonGenericDerived1 MyGenFunc(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 - ldstr "NonGenericDerived1 GenMiddleType.NewGenFunc1()" + ldstr "NonGenericDerived1 GenMiddleType.MyGenFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class GenDerive1> NewGenFunc2_Middle(string& res) + .method public hidebysig newslot virtual instance class GenDerive1> MyGenFunc(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 - ldstr "GenDerive1> GenMiddleType.NewGenFunc2()" + ldstr "GenDerive1> GenMiddleType.MyGenFunc()" stind.ref ldnull ret @@ -218,13 +209,17 @@ } +// ======================================================================================== +// 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 NonGenThroughGen4 NonGenThroughGenOverride(string& res) + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldarg.1 ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" @@ -233,303 +228,988 @@ ret } - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGen(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 - ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + ldstr "GenToNonGen3 TestType.GenToNonGen()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) + .method public hidebysig newslot virtual instance class NonGenericDerived4 MyGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 - ldstr "NonGenericDerived4 TestType.NewGenFunc1()" + ldstr "NonGenericDerived4 TestType.MyGenFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) + .method public hidebysig newslot virtual instance class GenDerive3 MyGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 - ldstr "GenDerive3 TestType.NewGenFunc2()" + ldstr "GenDerive3 TestType.MyGenFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) + .method public hidebysig newslot virtual instance class GenRetType MyFunc(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance object class GenBaseType::MyFunc(string& res) ldarg.1 - ldstr "GenRetType TestType.NewFunc1()" + ldstr "GenRetType TestType.MyFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + .method public hidebysig newslot virtual instance class C MyFunc(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc(string& res) ldarg.1 - ldstr "C TestType.NewFunc2()" + ldstr "C TestType.MyFunc()" 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 B NonGenThroughGenFunc(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + .method public hidebysig virtual instance class B GenToNonGen(string& res) { - .maxstack 8 - ldarg.0 - call instance void class GenMiddleType::.ctor() + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } + + .method public hidebysig virtual instance class GenRetType 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 GenRetType> 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 B MyFunc(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } +} + + +// ======================================================================================== +// FOURTH LAYER type: implicitly overrides all MethodImpls from GenTestType +// ======================================================================================== + +.class public auto ansi beforefieldinit ImplicitOverrideToMethodImpls extends class GenTestType +{ + .method public hidebysig virtual instance class NonGenThroughGen4 NonGenThroughGenFunc(string& res) + { + ldarg.1 + ldstr "NonGenThroughGen4 ImplicitOverrideToMethodImpls.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig virtual instance class GenToNonGen3 GenToNonGen(string& res) + { + ldarg.1 + ldstr "GenToNonGen3 ImplicitOverrideToMethodImpls.GenToNonGen()" + stind.ref + ldnull + ret + } + + .method public hidebysig virtual instance class NonGenericDerived4 MyGenFunc(string& res) + { + ldarg.1 + ldstr "NonGenericDerived4 ImplicitOverrideToMethodImpls.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig virtual instance class GenDerive3 MyGenFunc(string& res) + { + ldarg.1 + ldstr "GenDerive3 ImplicitOverrideToMethodImpls.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig virtual instance class GenRetType MyFunc(string& res) + { + ldarg.1 + ldstr "GenRetType ImplicitOverrideToMethodImpls.MyFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig virtual instance class C MyFunc(string& res) + { + ldarg.1 + ldstr "C ImplicitOverrideToMethodImpls.MyFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +// ======================================================================================== +// FOURTH LAYER type: overrides all MethodImpls from GenTestType using MethodImpls with the +// same return type used in GetTestType +// ======================================================================================== + +.class public auto ansi beforefieldinit ExplicitOverrideToMethodImpls extends class GenTestType +{ + .method public hidebysig virtual instance class NonGenThroughGen4 NonGenThroughGenFunc_MethodImpl(string& res) + { + .override method instance class NonGenThroughGen4 class GenTestType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 ExplicitOverrideToMethodImpls.NonGenThroughGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig virtual instance class GenToNonGen3 GenToNonGen_MethodImpl(string& res) + { + .override method instance class GenToNonGen3 class GenTestType::GenToNonGen(string& res) + ldarg.1 + ldstr "GenToNonGen3 ExplicitOverrideToMethodImpls.GenToNonGen()" + stind.ref + ldnull + ret + } + + .method public hidebysig virtual instance class NonGenericDerived4 MyGenFunc_MethodImpl(string& res) + { + .override method instance class NonGenericDerived4 class GenTestType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 ExplicitOverrideToMethodImpls.MyGenFunc()" + stind.ref + ldnull ret } + + .method public hidebysig virtual instance class GenDerive3 MyGenFunc_MethodImpl(string& res) + { + .override method instance class GenDerive3 class GenTestType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 ExplicitOverrideToMethodImpls.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig virtual instance class GenRetType MyFunc_MethodImpl(string& res) + { + .override method instance class GenRetType class GenTestType::MyFunc(string& res) + ldarg.1 + ldstr "GenRetType ExplicitOverrideToMethodImpls.MyFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig virtual instance class C MyFunc_MethodImpl(string& res) + { + .override method instance class C class GenTestType::MyFunc(string& res) + ldarg.1 + ldstr "C ExplicitOverrideToMethodImpls.MyFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } // ======================================================================================== .class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object { - // ============== Test using GenTestType ============== // + .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 GenTestType ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenMiddleType with covariant returns (when applicable) + // 3) The signature from GenTestType with covariant returns + // And verify that the override on GetTestType is the one that executes + .method public static bool RunTest1() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenRetType TestType.NewFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 callvirt instance object class GenBaseType::MyFunc(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class GenRetType class GenTestType::MyFunc(string&) + pop + + ldstr "GenRetType TestType.MyFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenRetType TestType.NewFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest2() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: C TestType.NewFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 callvirt instance class B class GenBaseType::MyFunc(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class C class GenTestType::MyFunc(string&) + pop + + ldstr "C TestType.MyFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "C TestType.NewFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest3() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenDerive3 TestType.NewGenFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class GenDerive1> class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class GenDerive3 class GenTestType::MyGenFunc(string&) + pop + + ldstr "GenDerive3 TestType.MyGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenDerive3 TestType.NewGenFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest4() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenericDerived4 TestType.NewGenFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class NonGenericDerived1 class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class NonGenericDerived4 class GenTestType::MyGenFunc(string&) + pop + + ldstr "NonGenericDerived4 TestType.MyGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenericDerived4 TestType.NewGenFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest5() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenToNonGen3 TestType.GenToNonGenOverride()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 callvirt instance class B class GenBaseType::GenToNonGen(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class GenToNonGen1> class GenMiddleType::GenToNonGen(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class GenToNonGen3 class GenTestType::GenToNonGen(string&) + pop + + ldstr "GenToNonGen3 TestType.GenToNonGen()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest6() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenThroughGen4 TestType.NonGenThroughGenFunc()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 - callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class NonGenThroughGen2 class GenMiddleType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class NonGenThroughGen4 class GenTestType::NonGenThroughGenFunc(string&) + pop + + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + // ============== Test using ImplicitOverrideToMethodImpls ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenMiddleType with covariant returns (when applicable) + // 3) The signature from GenTestType with covariant returns + // 4) The signature from ImplicitOverrideToMethodImpls + // And verify that the override on ImplicitOverrideToMethodImpls is the one that executes + + .method public static bool RunTest_ImplicitOverride1() noinlining + { + .locals init (string res1, string res2, string res3, string res4) - ldloc.0 - ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" - call bool [System.Runtime]System.String::op_Equality(string, string) + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 0 + callvirt instance object class GenBaseType::MyFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class GenRetType class GenTestType::MyFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class GenRetType class ImplicitOverrideToMethodImpls::MyFunc(string&) + pop + + ldstr "GenRetType ImplicitOverrideToMethodImpls.MyFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) ret } - // ============== Test using GenMiddleType ============== // - .method public static bool RunTest_Middle1() noinlining + .method public static bool RunTest_ImplicitOverride2() noinlining { - .locals init (string res, bool flag) + .locals init (string res1, string res2, string res3, string res4) - ldstr "EXPECTED: GenDerive1> GenMiddleType.NewGenFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::MyFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class C class GenTestType::MyFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class C class ImplicitOverrideToMethodImpls::MyFunc(string&) + pop + + ldstr "C ImplicitOverrideToMethodImpls.MyFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_ImplicitOverride3() noinlining + { + .locals init (string res1, string res2, string res3, string res4) - newobj instance void class GenMiddleType::.ctor() + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() ldloca.s 0 callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class GenDerive1> class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class GenDerive3 class GenTestType::MyGenFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 3 + callvirt instance class GenDerive3 class ImplicitOverrideToMethodImpls::MyGenFunc(string&) + pop + + ldstr "GenDerive3 ImplicitOverrideToMethodImpls.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_ImplicitOverride4() noinlining + { + .locals init (string res1, string res2, string res3, string res4) + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 0 + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class NonGenericDerived1 class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class NonGenericDerived4 class GenTestType::MyGenFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 3 + callvirt instance class NonGenericDerived4 class ImplicitOverrideToMethodImpls::MyGenFunc(string&) + pop + + ldstr "NonGenericDerived4 ImplicitOverrideToMethodImpls.MyGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_ImplicitOverride5() noinlining + { + .locals init (string res1, string res2, string res3, string res4) - ldloc.0 - ldstr "GenDerive1> GenMiddleType.NewGenFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::GenToNonGen(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class GenToNonGen1> class GenMiddleType::GenToNonGen(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class GenToNonGen3 class GenTestType::GenToNonGen(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 3 + callvirt instance class GenToNonGen3 class ImplicitOverrideToMethodImpls::GenToNonGen(string&) + pop + + ldstr "GenToNonGen3 ImplicitOverrideToMethodImpls.GenToNonGen()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) ret } - .method public static bool RunTest_Middle2() noinlining + .method public static bool RunTest_ImplicitOverride6() noinlining { - .locals init (string res, bool flag) + .locals init (string res1, string res2, string res3, string res4) - ldstr "EXPECTED: NonGenericDerived1 GenMiddleType.NewGenFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class NonGenThroughGen2 class GenMiddleType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class NonGenThroughGen4 class GenTestType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class ImplicitOverrideToMethodImpls::.ctor() + ldloca.s 3 + callvirt instance class NonGenThroughGen4 class ImplicitOverrideToMethodImpls::NonGenThroughGenFunc(string&) + pop + + ldstr "NonGenThroughGen4 ImplicitOverrideToMethodImpls.NonGenThroughGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + // ============== Test using ExplicitOverrideToMethodImpls ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenMiddleType with covariant returns (when applicable) + // 3) The signature from GenTestType with covariant returns + // 4) The signature from ExplicitOverrideToMethodImpls + // And verify that the override on ExplicitOverrideToMethodImpls is the one that executes + + .method public static bool RunTest_ExplicitOverride1() noinlining + { + .locals init (string res1, string res2, string res3, string res4) - newobj instance void class GenMiddleType::.ctor() + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() ldloca.s 0 - callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + callvirt instance object class GenBaseType::MyFunc(string&) pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class GenRetType class GenTestType::MyFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class GenRetType class ExplicitOverrideToMethodImpls::MyFunc(string&) + pop + + ldstr "GenRetType ExplicitOverrideToMethodImpls.MyFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_ExplicitOverride2() noinlining + { + .locals init (string res1, string res2, string res3, string res4) + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::MyFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class C class GenTestType::MyFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class C class ExplicitOverrideToMethodImpls::MyFunc(string&) + pop + + ldstr "C ExplicitOverrideToMethodImpls.MyFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_ExplicitOverride3() noinlining + { + .locals init (string res1, string res2, string res3, string res4) - ldloc.0 - ldstr "NonGenericDerived1 GenMiddleType.NewGenFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 0 + callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class GenDerive1> class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class GenDerive3 class GenTestType::MyGenFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 3 + callvirt instance class GenDerive3 class ExplicitOverrideToMethodImpls::MyGenFunc(string&) + pop + + ldstr "GenDerive3 ExplicitOverrideToMethodImpls.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) ret } - .method public static bool RunTest_Middle3() noinlining + .method public static bool RunTest_ExplicitOverride4() noinlining { - .locals init (string res, bool flag) + .locals init (string res1, string res2, string res3, string res4) - ldstr "EXPECTED: GenToNonGen1> GenMiddleType.GenToNonGenOverride()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 0 + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class NonGenericDerived1 class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class NonGenericDerived4 class GenTestType::MyGenFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 3 + callvirt instance class NonGenericDerived4 class ExplicitOverrideToMethodImpls::MyGenFunc(string&) + pop + + ldstr "NonGenericDerived4 ExplicitOverrideToMethodImpls.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_ExplicitOverride5() noinlining + { + .locals init (string res1, string res2, string res3, string res4) - newobj instance void class GenMiddleType::.ctor() + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() ldloca.s 0 callvirt instance class B class GenBaseType::GenToNonGen(string&) pop - + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class GenToNonGen1> class GenMiddleType::GenToNonGen(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class GenToNonGen3 class GenTestType::GenToNonGen(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 3 + callvirt instance class GenToNonGen3 class ExplicitOverrideToMethodImpls::GenToNonGen(string&) + pop + + ldstr "GenToNonGen3 ExplicitOverrideToMethodImpls.GenToNonGen()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_ExplicitOverride6() noinlining + { + .locals init (string res1, string res2, string res3, string res4) - ldloc.0 - ldstr "GenToNonGen1> GenMiddleType.GenToNonGenOverride()" - call bool [System.Runtime]System.String::op_Equality(string, string) + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 1 + callvirt instance class NonGenThroughGen2 class GenMiddleType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 2 + callvirt instance class NonGenThroughGen4 class GenTestType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class ExplicitOverrideToMethodImpls::.ctor() + ldloca.s 3 + callvirt instance class NonGenThroughGen4 class ExplicitOverrideToMethodImpls::NonGenThroughGenFunc(string&) + pop + + ldstr "NonGenThroughGen4 ExplicitOverrideToMethodImpls.NonGenThroughGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) ret } - .method public static bool RunTest_Middle4() noinlining + // ============== Test using GenMiddleType ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenMiddleType with covariant returns + // And verify that the override on GenMiddleType is the one that executes + + .method public static bool RunTest_Middle1() noinlining { - .locals init (string res, bool flag) + .locals init (string res1, string res2, string res3) - ldstr "EXPECTED: NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class GenDerive1> class GenMiddleType::MyGenFunc(string&) + pop + + ldstr "GenDerive1> GenMiddleType.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_Middle2() noinlining + { + .locals init (string res1, string res2, string res3) - newobj instance void class GenMiddleType::.ctor() + newobj instance void class GenMiddleType::.ctor() ldloca.s 0 - callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class NonGenericDerived1 class GenMiddleType::MyGenFunc(string&) pop + + ldstr "NonGenericDerived1 GenMiddleType.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_Middle3() noinlining + { + .locals init (string res1, string res2, string res3) + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::GenToNonGen(string&) + pop + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class GenToNonGen1> class GenMiddleType::GenToNonGen(string&) + pop + + ldstr "GenToNonGen1> GenMiddleType.GenToNonGen()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_Middle4() noinlining + { + .locals init (string res1, string res2, string res3) - ldloc.0 - ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" - call bool [System.Runtime]System.String::op_Equality(string, string) + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class NonGenThroughGen2 class GenMiddleType::NonGenThroughGenFunc(string&) + pop + + ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } @@ -580,6 +1260,8 @@ ldc.i4.0 stloc.0 + // ===================================================================================== // + M1: call bool CMain::RunTest_Middle1() brtrue.s M2 @@ -600,10 +1282,88 @@ M4: call bool CMain::RunTest_Middle4() - brtrue.s DONE + brtrue.s IMP_OVERRIDE1 + ldc.i4.0 + stloc.0 + + // ===================================================================================== // + + IMP_OVERRIDE1: + call bool CMain::RunTest_ImplicitOverride1() + brtrue.s IMP_OVERRIDE2 + ldc.i4.0 + stloc.0 + + IMP_OVERRIDE2: + call bool CMain::RunTest_ImplicitOverride2() + brtrue.s IMP_OVERRIDE3 + ldc.i4.0 + stloc.0 + + IMP_OVERRIDE3: + call bool CMain::RunTest_ImplicitOverride3() + brtrue.s IMP_OVERRIDE4 ldc.i4.0 stloc.0 + IMP_OVERRIDE4: + call bool CMain::RunTest_ImplicitOverride4() + brtrue.s IMP_OVERRIDE5 + ldc.i4.0 + stloc.0 + + IMP_OVERRIDE5: + call bool CMain::RunTest_ImplicitOverride5() + brtrue.s IMP_OVERRIDE6 + ldc.i4.0 + stloc.0 + + IMP_OVERRIDE6: + call bool CMain::RunTest_ImplicitOverride6() + brtrue.s EXP_OVERRIDE1 + ldc.i4.0 + stloc.0 + + // ===================================================================================== // + + EXP_OVERRIDE1: + call bool CMain::RunTest_ExplicitOverride1() + brtrue.s EXP_OVERRIDE2 + ldc.i4.0 + stloc.0 + + EXP_OVERRIDE2: + call bool CMain::RunTest_ExplicitOverride2() + brtrue.s EXP_OVERRIDE3 + ldc.i4.0 + stloc.0 + + EXP_OVERRIDE3: + call bool CMain::RunTest_ExplicitOverride3() + brtrue.s EXP_OVERRIDE4 + ldc.i4.0 + stloc.0 + + EXP_OVERRIDE4: + call bool CMain::RunTest_ExplicitOverride4() + brtrue.s EXP_OVERRIDE5 + ldc.i4.0 + stloc.0 + + EXP_OVERRIDE5: + call bool CMain::RunTest_ExplicitOverride5() + brtrue.s EXP_OVERRIDE6 + ldc.i4.0 + stloc.0 + + EXP_OVERRIDE6: + call bool CMain::RunTest_ExplicitOverride6() + brtrue.s DONE + ldc.i4.0 + stloc.0 + + // ===================================================================================== // + DONE: ldloc.0 brtrue.s PASS diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il index 5edc688108eaf1..343e0e580aeba4 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il @@ -8,6 +8,10 @@ .assembly extern mscorlib { } .assembly UnitTest_GVM { } +// ======================================================================================== +// 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 } @@ -100,15 +104,13 @@ } +// ======================================================================================== +// Main base type with various virtual methods that will be overriden later +// ======================================================================================== + .class public auto ansi beforefieldinit GenBaseType { - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .method public hidebysig newslot virtual instance object MyFunc(string& res) { @@ -158,30 +160,19 @@ newobj instance void class GenRetType>::.ctor() ret } - .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) - { - ldarg.1 - ldstr "GenRetType GenBaseType.TestNonGenericDerived()" - 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 - { - .maxstack 8 - ldarg.0 - call instance void class GenBaseType::.ctor() - ret - } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } - .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenOverride_Middle(string& res) + .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenFunc(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) @@ -192,47 +183,49 @@ ret } - .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGenOverride_Middle(string& res) + .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGen(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) ldarg.1 - ldstr "GenToNonGen1> GenMiddleType.GenToNonGenOverride()" + ldstr "GenToNonGen1> GenMiddleType.GenToNonGen()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class NonGenericDerived1 NewGenFunc1_Middle(string& res) + .method public hidebysig newslot virtual instance class NonGenericDerived1 MyGenFunc(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) ldarg.1 - ldstr "NonGenericDerived1 GenMiddleType.NewGenFunc1()" + ldstr "NonGenericDerived1 GenMiddleType.MyGenFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class GenDerive2 NewGenFunc2_Middle(string& res) + .method public hidebysig newslot virtual instance class GenDerive1> MyGenFunc(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) ldarg.1 - ldstr "GenDerive2 GenMiddleType.NewGenFunc2()" + 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 NonGenThroughGenOverride(string& res) + .method public hidebysig newslot virtual instance class NonGenThroughGen5 NonGenThroughGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) ldarg.1 ldstr "NonGenThroughGen5 TestType.NonGenThroughGenFunc()" @@ -241,70 +234,65 @@ ret } - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGen(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) ldarg.1 - ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" + ldstr "GenToNonGen3 TestType.GenToNonGen()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class NonGenericDerived5 NewGenFunc1(string& res) + .method public hidebysig newslot virtual instance class NonGenericDerived5 MyGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) ldarg.1 - ldstr "NonGenericDerived5 TestType.NewGenFunc1()" + ldstr "NonGenericDerived5 TestType.MyGenFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class GenDerive2 NewGenFunc2(string& res) + .method public hidebysig newslot virtual instance class GenDerive2 MyGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) ldarg.1 - ldstr "GenDerive2 TestType.NewGenFunc2()" + ldstr "GenDerive2 TestType.MyGenFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) + .method public hidebysig newslot virtual instance class GenRetType MyFunc(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance object class GenBaseType::MyFunc<[1]>(string& res) ldarg.1 - ldstr "GenRetType TestType.NewFunc1()" + ldstr "GenRetType TestType.MyFunc()" stind.ref ldnull ret } - .method public hidebysig newslot virtual instance class C NewFunc2(string& res) + .method public hidebysig newslot virtual instance class C MyFunc(string& res) { .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc<[1]>(string& res) ldarg.1 - ldstr "C TestType.NewFunc2()" + ldstr "C TestType.MyFunc()" stind.ref ldnull ret } - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenMiddleType::.ctor() - 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 @@ -312,7 +300,6 @@ // 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) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) ldnull ret @@ -324,7 +311,6 @@ // Invalid: when comparing 'object' with !!Y in the instantiation .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) ldnull ret @@ -336,7 +322,6 @@ // Invalid when comparing !!Y and 'object' in instantiation of GenRetType .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) ldnull ret @@ -348,7 +333,6 @@ // Invalid when comparing !!Y and 'string' in instantiation of Dictionary .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) ldnull ret @@ -360,239 +344,367 @@ .class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object { - // ============== Test using GenTestType ============== // + .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 GenTestType ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenMiddleType with covariant returns (when applicable) + // 3) The signature from GenTestType with covariant returns + // And verify that the override on GetTestType is the one that executes + .method public static bool RunTest1() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenRetType TestType.NewFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 callvirt instance object class GenBaseType::MyFunc(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class GenRetType class GenTestType::MyFunc(string&) + pop + + ldstr "GenRetType TestType.MyFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenRetType TestType.NewFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest2() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: C TestType.NewFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 callvirt instance class B class GenBaseType::MyFunc(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class C class GenTestType::MyFunc(string&) + pop + + ldstr "C TestType.MyFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "C TestType.NewFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest3() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenDerive2 TestType.NewGenFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class GenDerive1> class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class GenDerive2 class GenTestType::MyGenFunc(string&) + pop + + ldstr "GenDerive2 TestType.MyGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenDerive2 TestType.NewGenFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest4() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenericDerived5 TestType.NewGenFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class NonGenericDerived1 class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class NonGenericDerived5 class GenTestType::MyGenFunc(string&) + pop + + ldstr "NonGenericDerived5 TestType.MyGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenericDerived5 TestType.NewGenFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest5() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenToNonGen3 TestType.GenToNonGenOverride()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 callvirt instance class B class GenBaseType::GenToNonGen(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class GenToNonGen1> class GenMiddleType::GenToNonGen(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class GenToNonGen3 class GenTestType::GenToNonGen(string&) + pop + + ldstr "GenToNonGen3 TestType.GenToNonGen()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest6() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenThroughGen5 TestType.NonGenThroughGenFunc()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenTestType::.ctor() ldloca.s 0 - callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string&) pop - + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class NonGenThroughGen2 class GenMiddleType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class NonGenThroughGen5 class GenTestType::NonGenThroughGenFunc(string&) + pop + + ldstr "NonGenThroughGen5 TestType.NonGenThroughGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenThroughGen5 TestType.NonGenThroughGenFunc()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } - // ============== Test using GenMiddleType ============== // + // ============== Test using GenMiddleType ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenMiddleType with covariant returns + // And verify that the override on GenMiddleType is the one that executes + .method public static bool RunTest_Middle1() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenDerive2 GenMiddleType.NewGenFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenMiddleType::.ctor() ldloca.s 0 - callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) + callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) pop - + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class GenDerive1> class GenMiddleType::MyGenFunc(string&) + pop + + ldstr "GenDerive1> GenMiddleType.MyGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenDerive2 GenMiddleType.NewGenFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest_Middle2() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenericDerived1 GenMiddleType.NewGenFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenMiddleType::.ctor() ldloca.s 0 - callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) + callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) pop - + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class NonGenericDerived1 class GenMiddleType::MyGenFunc(string&) + pop + + ldstr "NonGenericDerived1 GenMiddleType.MyGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenericDerived1 GenMiddleType.NewGenFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest_Middle3() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenToNonGen1> GenMiddleType.GenToNonGenOverride()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenMiddleType::.ctor() ldloca.s 0 - callvirt instance class B class GenBaseType::GenToNonGen(string&) + callvirt instance class B class GenBaseType::GenToNonGen(string&) pop - + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class GenToNonGen1> class GenMiddleType::GenToNonGen(string&) + pop + + ldstr "GenToNonGen1> GenMiddleType.GenToNonGen()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenToNonGen1> GenMiddleType.GenToNonGenOverride()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) ret } .method public static bool RunTest_Middle4() noinlining { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) + .locals init (string res1, string res2, string res3) newobj instance void class GenMiddleType::.ctor() ldloca.s 0 - callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string&) pop - + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class NonGenThroughGen2 class GenMiddleType::NonGenThroughGenFunc(string&) + pop + + ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" - call bool [System.Runtime]System.String::op_Equality(string, string) + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) 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() diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il deleted file mode 100644 index 3dbed8ce83a035..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/ImplicitOverrideSameSigAsDecl.il +++ /dev/null @@ -1,574 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -.assembly extern System.Console { } -.assembly extern System.Private.CoreLib { } -.assembly extern System.Runtime { } -.assembly extern mscorlib { } -.assembly ImplicitOverrideSameSigAsDecl { } - -.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 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 GenBaseType -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - 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 - } - .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) - { - ldarg.1 - ldstr "GenRetType GenBaseType.TestNonGenericDerived()" - stind.ref - newobj instance void class GenRetType::.ctor() - ret - } -} - - -// ======================================================================================== - -.class public auto ansi beforefieldinit GenTestType extends class GenBaseType -{ - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) - { - .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) - ldarg.1 - ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) - { - .override method instance class B class GenBaseType::GenToNonGen(string& res) - ldarg.1 - ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) - { - .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) - ldarg.1 - ldstr "NonGenericDerived4 TestType.NewGenFunc1()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) - { - .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) - ldarg.1 - ldstr "GenDerive3 TestType.NewGenFunc2()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) - { - .override method instance object class GenBaseType::MyFunc(string& res) - ldarg.1 - ldstr "GenRetType TestType.NewFunc1()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class C NewFunc2(string& res) - { - .override method instance class B class GenBaseType::MyFunc(string& res) - ldarg.1 - ldstr "C TestType.NewFunc2()" - stind.ref - ldnull - ret - } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenBaseType::.ctor() - ret - } -} - -// ======================================================================================== - -.class public auto ansi beforefieldinit DerivedTestType extends class GenTestType -{ - .method public hidebysig virtual instance object MyFunc(string& res) - { - // Attribute ignored since this is not a MethodImpl - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - ldarg.1 - ldstr "object DerivedTestType.MyFunc()" - stind.ref - newobj instance void A::.ctor() - ret - } - - .method public hidebysig virtual instance class B MyFunc(string& res) - { - // Attribute ignored since this is not a MethodImpl - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - ldarg.1 - ldstr "B DerivedTestType.MyFunc()" - stind.ref - newobj instance void B::.ctor() - ret - } - - .method public hidebysig virtual instance class B GenToNonGen(string& res) - { - // Attribute ignored since this is not a MethodImpl - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - ldarg.1 - ldstr "B DerivedTestType.GenToNonGen()" - stind.ref - newobj instance void B::.ctor() - ret - } - - .method public hidebysig virtual instance class B NonGenThroughGenFunc(string& res) - { - // Attribute ignored since this is not a MethodImpl - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - ldarg.1 - ldstr "B DerivedTestType.NonGenThroughGenFunc()" - stind.ref - newobj instance void B::.ctor() - ret - } - - .method public hidebysig virtual instance class GenRetType MyGenFunc(string& res) - { - // Attribute ignored since this is not a MethodImpl - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - ldarg.1 - ldstr "GenRetType DerivedTestType.MyGenFunc()" - stind.ref - newobj instance void class GenRetType::.ctor() - ret - } - - .method public hidebysig virtual instance class GenRetType> MyGenFunc(string& res) - { - // Attribute ignored since this is not a MethodImpl - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - ldarg.1 - ldstr "GenRetType> DerivedTestType.MyGenFunc()" - stind.ref - newobj instance void class GenRetType>::.ctor() - ret - } - - .method public hidebysig virtual instance class GenRetType TestNonGenericDerived(string& res) - { - // Attribute ignored since this is not a MethodImpl - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) - ldarg.1 - ldstr "GenRetType DerivedTestType.TestNonGenericDerived()" - stind.ref - newobj instance void class GenRetType::.ctor() - ret - } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} - -// ======================================================================================== - -.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object -{ - .method public static bool RunTest1() noinlining - { - .locals init (string res, bool flag, string expected) - - ldstr "object DerivedTestType.MyFunc()" - stloc.2 - - ldstr "EXPECTED: " - call void [System.Console]System.Console::Write(object) - ldloc.2 - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class DerivedTestType::.ctor() - ldloca.s 0 - callvirt instance object class GenBaseType::MyFunc(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldloc.2 - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest2() noinlining - { - .locals init (string res, bool flag, string expected) - - ldstr "B DerivedTestType.MyFunc()" - stloc.2 - - ldstr "EXPECTED: " - call void [System.Console]System.Console::Write(object) - ldloc.2 - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class DerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class B class GenBaseType::MyFunc(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldloc.2 - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest3() noinlining - { - .locals init (string res, bool flag, string expected) - - ldstr "B DerivedTestType.GenToNonGen()" - stloc.2 - - ldstr "EXPECTED: " - call void [System.Console]System.Console::Write(object) - ldloc.2 - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class DerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class B class GenBaseType::GenToNonGen(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldloc.2 - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest4() noinlining - { - .locals init (string res, bool flag, string expected) - - ldstr "B DerivedTestType.NonGenThroughGenFunc()" - stloc.2 - - ldstr "EXPECTED: " - call void [System.Console]System.Console::Write(object) - ldloc.2 - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class DerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class B class GenBaseType::NonGenThroughGenFunc(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldloc.2 - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest5() noinlining - { - .locals init (string res, bool flag, string expected) - - ldstr "GenRetType DerivedTestType.MyGenFunc()" - stloc.2 - - ldstr "EXPECTED: " - call void [System.Console]System.Console::Write(object) - ldloc.2 - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class DerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class GenRetType class GenBaseType::MyGenFunc(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldloc.2 - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest6() noinlining - { - .locals init (string res, bool flag, string expected) - - ldstr "GenRetType> DerivedTestType.MyGenFunc()" - stloc.2 - - ldstr "EXPECTED: " - call void [System.Console]System.Console::Write(object) - ldloc.2 - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class DerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class GenRetType> class GenBaseType::MyGenFunc(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldloc.2 - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest7() noinlining - { - .locals init (string res, bool flag, string expected) - - ldstr "GenRetType DerivedTestType.TestNonGenericDerived()" - stloc.2 - - ldstr "EXPECTED: " - call void [System.Console]System.Console::Write(object) - ldloc.2 - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class DerivedTestType::.ctor() - ldloca.s 0 - callvirt instance class GenRetType class GenBaseType::TestNonGenericDerived(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldloc.2 - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public hidebysig static int32 Main( string[] args) cil managed - { - .entrypoint - .maxstack 2 - .locals init ( bool result ) - - ldc.i4.1 - stloc.0 - - T1: - call bool CMain::RunTest1() - brtrue.s T2 - ldc.i4.0 - stloc.0 - - T2: - call bool CMain::RunTest2() - brtrue.s T3 - ldc.i4.0 - stloc.0 - - T3: - call bool CMain::RunTest3() - brtrue.s T4 - ldc.i4.0 - stloc.0 - - T4: - call bool CMain::RunTest4() - brtrue.s T5 - ldc.i4.0 - stloc.0 - - T5: - call bool CMain::RunTest5() - brtrue.s T6 - ldc.i4.0 - stloc.0 - - T6: - call bool CMain::RunTest6() - brtrue.s T7 - ldc.i4.0 - stloc.0 - - T7: - call bool CMain::RunTest7() - brtrue.s DONE - ldc.i4.0 - stloc.0 - - DONE: - - ldloc.0 - brtrue.s PASS - - ldc.i4.s 101 - ret - - PASS: - ldstr "Test PASSED" - call void [System.Console]System.Console::WriteLine(string) - 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/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.ilproj deleted file mode 100644 index 01553924a15bbe..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Validation/IncompatibleReturnNoValidation.ilproj +++ /dev/null @@ -1,10 +0,0 @@ - - - Exe - BuildAndRun - 0 - - - - - From 698eafb0211a8c2775b83ba745416e3c1f1aa029 Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Wed, 29 Apr 2020 13:29:53 -0700 Subject: [PATCH 07/21] Rename attribute and reference it from System.Runtime instead of S.P.C --- docs/design/features/covariant-return-methods.md | 8 ++++---- src/coreclr/src/vm/class.cpp | 6 +++--- src/coreclr/src/vm/wellknownattributes.h | 6 +++--- .../ImplicitOverrideSameSigAsDecl.il | 1 - .../ReturnTypeValidation/OverrideSameSigAsDecl.il | 1 - .../CovariantReturns/UnitTest/AttributeTesting.il | 8 ++++---- .../UnitTest/OverrideMoreDerivedReturn.il | 12 ++++++------ .../CovariantReturns/UnitTest/UnitTest.il | 13 ++++++------- .../CovariantReturns/UnitTest/UnitTest_GVM.il | 13 ++++++------- .../src/System.Private.CoreLib.Shared.projitems | 2 +- ...> RequireMethodImplToRemainInEffectAttribute.cs} | 2 +- src/libraries/System.Runtime/ref/System.Runtime.cs | 5 +++++ 12 files changed, 39 insertions(+), 38 deletions(-) rename src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/{ValidateMethodImplRemainsInEffectAttribute.cs => RequireMethodImplToRemainInEffectAttribute.cs} (85%) diff --git a/docs/design/features/covariant-return-methods.md b/docs/design/features/covariant-return-methods.md index 0bc9c541cbf839..8bf067d698414a 100644 --- a/docs/design/features/covariant-return-methods.md +++ b/docs/design/features/covariant-return-methods.md @@ -12,7 +12,7 @@ If a language wishes for the override to be semantically visible such that users For virtual method slot MethodImpl overrides, each slot shall be checked for compatible signature on type load. (Implementation note: This behavior can be triggered only if the type has a covariant return type override in its hierarchy, so as to make this pay for play.) -A new `ValidateMethodImplRemainsInEffectAttribute` shall be added. The presence of this attribute is to require the type loader to ensure that the MethodImpl records specified on the method have not lost their slot unifying behavior due to other actions. This is used to allow the C# language to require that overrides have the consistent behaviors expected. The expectation is that C# would place this attribute on covariant override methods in classes. +A new `RequireMethodImplToRemainInEffectAttribute` shall be added. The presence of this attribute is to require the type loader to ensure that the MethodImpl records specified on the method have not lost their slot unifying behavior due to other actions. This is used to allow the C# language to require that overrides have the consistent behaviors expected. The expectation is that C# would place this attribute on covariant override methods in classes. ## Implementation Notes @@ -29,7 +29,7 @@ Once a method is flagged for return type checking, every time the vtable slot co ### VTable Slot Unification -If a MethodImpl has the `ValidateMethodImplRemainsInEffectAttribute` attribute, it needs to propagate all applicable vtable slots on the type. This is to ensure that if we use the signature of one of the base type methods to call the overriding method, we still execute the overriding method. +If a MethodImpl has the `RequireMethodImplToRemainInEffectAttribute` attribute, it needs to propagate all applicable vtable slots on the type. This is to ensure that if we use the signature of one of the base type methods to call the overriding method, we still execute the overriding method. Consider this case: ``` C# @@ -37,11 +37,11 @@ Consider this case: RetType VirtualFunction() { } } class B : A { - [ValidateMethodImplRemainsInEffect] + [RequireMethodImplToRemainInEffect] DerivedRetType VirtualFunction() { .override A.VirtualFuncion } } class C : B { - [ValidateMethodImplRemainsInEffect] + [RequireMethodImplToRemainInEffect] MoreDerivedRetType VirtualFunction() { .override A.VirtualFunction } } ``` diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index ee5c61dfd13c20..d3d9cde85b3c01 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -993,7 +993,7 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) // ECMA I.8.7.1, which is what the CanCastTo() API checks. // // The second step is to propagate an overriding MethodImpl to all applicable vtable slots if the MethodImpl - // has the ValidateMethodImplRemainsInEffect attribute. This is to ensure that if we use the signature of one of + // has the RequireMethodImplToRemainInEffect attribute. This is to ensure that if we use the signature of one of // the base type methods to call the overriding method, we still execute the overriding method. // // Consider this case: @@ -1002,7 +1002,7 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) // RetType VirtualFunction() { } // } // class B : A { - // [ValidateMethodImplRemainsInEffect] + // [RequireMethodImplToRemainInEffect] // DerivedRetType VirtualFunction() { .override A.VirtualFuncion } // } // class C : B { @@ -1118,7 +1118,7 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) { BYTE* pVal = NULL; ULONG cbVal = 0; - if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::ValidateMethodImplRemainsInEffectAttribute, (const void**)&pVal, &cbVal) == S_OK) + if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::RequireMethodImplToRemainInEffectAttribute, (const void**)&pVal, &cbVal) == S_OK) foundAttribute = true; } diff --git a/src/coreclr/src/vm/wellknownattributes.h b/src/coreclr/src/vm/wellknownattributes.h index 8401f233cd0c56..c5bbcc5d4279a2 100644 --- a/src/coreclr/src/vm/wellknownattributes.h +++ b/src/coreclr/src/vm/wellknownattributes.h @@ -35,7 +35,7 @@ enum class WellKnownAttribute : DWORD UnmanagedFunctionPointer, ThreadStatic, WinRTMarshalingBehaviorAttribute, - ValidateMethodImplRemainsInEffectAttribute, + RequireMethodImplToRemainInEffectAttribute, CountOfWellKnownAttributes }; @@ -100,8 +100,8 @@ inline const char *GetWellKnownAttributeName(WellKnownAttribute attribute) return "System.ThreadStaticAttribute"; case WellKnownAttribute::WinRTMarshalingBehaviorAttribute: return "Windows.Foundation.Metadata.MarshalingBehaviorAttribute"; - case WellKnownAttribute::ValidateMethodImplRemainsInEffectAttribute: - return "System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute"; + case WellKnownAttribute::RequireMethodImplToRemainInEffectAttribute: + return "System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute"; case WellKnownAttribute::CountOfWellKnownAttributes: default: break; // Silence compiler warnings diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/ImplicitOverrideSameSigAsDecl.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/ImplicitOverrideSameSigAsDecl.il index 09ed573cf8b59c..facd99dbe81f66 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/ImplicitOverrideSameSigAsDecl.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/ImplicitOverrideSameSigAsDecl.il @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. .assembly extern System.Console { } -.assembly extern System.Private.CoreLib { } .assembly extern System.Runtime { } .assembly extern mscorlib { } .assembly ImplicitOverrideSameSigAsDecl { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/OverrideSameSigAsDecl.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/OverrideSameSigAsDecl.il index 16b8da89179207..4d497eef358e2a 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/OverrideSameSigAsDecl.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/ReturnTypeValidation/OverrideSameSigAsDecl.il @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. .assembly extern System.Console { } -.assembly extern System.Private.CoreLib { } .assembly extern System.Runtime { } .assembly extern mscorlib { } .assembly OverrideSameSigAsDecl { } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il index fcdb89f5ac67de..e920a66bbfb1ab 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -// This test validates the behavior in the presence/absence of the ValidateMethodImplRemainsInEffectAttribute. +// This test validates the behavior in the presence/absence of the RequireMethodImplToRemainInEffectAttribute. // 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) @@ -57,7 +57,7 @@ .method public hidebysig newslot virtual instance string Func1() { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) ldstr "T1" ret } @@ -250,7 +250,7 @@ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .method public hidebysig newslot virtual instance string Func2() { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance string class C.T1::Func1() ldstr "T2" ret @@ -321,7 +321,7 @@ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .method public hidebysig virtual instance string Func1() { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) ldstr "T2" ret } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il index 8450a1e6c7bed6..cc28520ffb56ed 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il @@ -268,7 +268,7 @@ { .method public hidebysig newslot virtual instance class NonGenThroughGen5 NonGenThroughGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldarg.1 ldstr "NonGenThroughGen5 DerivedTestType.NonGenThroughGenFunc()" @@ -279,7 +279,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen4 GenToNonGen(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 ldstr "GenToNonGen4 DerivedTestType.GenToNonGen()" @@ -290,7 +290,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived5 MyGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "NonGenericDerived5 DerivedTestType.MyGenFunc()" @@ -301,7 +301,7 @@ .method public hidebysig newslot virtual instance class GenDerive4 MyGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "GenDerive4 DerivedTestType.MyGenFunc()" @@ -312,7 +312,7 @@ .method public hidebysig newslot virtual instance class GenDerivedRetType2 MyFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance object class GenBaseType::MyFunc(string& res) ldarg.1 ldstr "GenDerivedRetType2 DerivedTestType.MyFunc()" @@ -323,7 +323,7 @@ .method public hidebysig newslot virtual instance class D MyFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc(string& res) ldarg.1 ldstr "D DerivedTestType.MyFunc()" diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il index e124ae2f896760..950ec5c9120ad6 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il @@ -4,7 +4,6 @@ .assembly extern System.Console { } .assembly extern System.Runtime { } -.assembly extern System.Private.CoreLib { } .assembly extern mscorlib { } .assembly UnitTest { } @@ -165,7 +164,7 @@ .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldarg.1 ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" @@ -176,7 +175,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGen(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 ldstr "GenToNonGen1> GenMiddleType.GenToNonGen()" @@ -187,7 +186,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived1 MyGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "NonGenericDerived1 GenMiddleType.MyGenFunc()" @@ -198,7 +197,7 @@ .method public hidebysig newslot virtual instance class GenDerive1> MyGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "GenDerive1> GenMiddleType.MyGenFunc()" @@ -260,7 +259,7 @@ .method public hidebysig newslot virtual instance class GenRetType MyFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance object class GenBaseType::MyFunc(string& res) ldarg.1 ldstr "GenRetType TestType.MyFunc()" @@ -271,7 +270,7 @@ .method public hidebysig newslot virtual instance class C MyFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc(string& res) ldarg.1 ldstr "C TestType.MyFunc()" diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il index 343e0e580aeba4..8f9e4933414e20 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il @@ -4,7 +4,6 @@ .assembly extern System.Console { } .assembly extern System.Runtime { } -.assembly extern System.Private.CoreLib { } .assembly extern mscorlib { } .assembly UnitTest_GVM { } @@ -174,7 +173,7 @@ .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc<[1]>(string& res) ldarg.1 ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" @@ -185,7 +184,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGen(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen<[1]>(string& res) ldarg.1 ldstr "GenToNonGen1> GenMiddleType.GenToNonGen()" @@ -196,7 +195,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived1 MyGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc<[1]>(string& res) ldarg.1 ldstr "NonGenericDerived1 GenMiddleType.MyGenFunc()" @@ -207,7 +206,7 @@ .method public hidebysig newslot virtual instance class GenDerive1> MyGenFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc<[1]>(string& res) ldarg.1 ldstr "GenDerive1> GenMiddleType.MyGenFunc()" @@ -266,7 +265,7 @@ .method public hidebysig newslot virtual instance class GenRetType MyFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance object class GenBaseType::MyFunc<[1]>(string& res) ldarg.1 ldstr "GenRetType TestType.MyFunc()" @@ -277,7 +276,7 @@ .method public hidebysig newslot virtual instance class C MyFunc(string& res) { - .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.ValidateMethodImplRemainsInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc<[1]>(string& res) ldarg.1 ldstr "C TestType.MyFunc()" diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 095e1281bf3b06..03a793d83184b2 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -633,6 +633,7 @@ + @@ -649,7 +650,6 @@ - diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RequireMethodImplToRemainInEffectAttribute.cs similarity index 85% rename from src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs rename to src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RequireMethodImplToRemainInEffectAttribute.cs index c289981fdd58df..8ffbf8484b3d07 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValidateMethodImplRemainsInEffectAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RequireMethodImplToRemainInEffectAttribute.cs @@ -5,7 +5,7 @@ namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] - public sealed class ValidateMethodImplRemainsInEffectAttribute : Attribute + public sealed class RequireMethodImplToRemainInEffectAttribute : Attribute { } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 52b631512e1da7..08b0243639ba6a 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -9151,6 +9151,11 @@ public void OnCompleted(System.Action continuation) { } public void UnsafeOnCompleted(System.Action continuation) { } } } + [System.AttributeUsageAttribute(System.AttributeTargets.Method, Inherited = false, AllowMultiple = false)] + public sealed partial class RequireMethodImplToRemainInEffectAttribute : System.Attribute + { + public RequireMethodImplToRemainInEffectAttribute() { } + } } namespace System.Runtime.ConstrainedExecution { From 6848c405f0c889e7818102b8b5c5801764b7fcf5 Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Wed, 29 Apr 2020 16:52:42 -0700 Subject: [PATCH 08/21] Add test coverage for interface cases. Fixed an assert --- src/coreclr/src/vm/class.cpp | 4 + src/coreclr/src/vm/methodtable.cpp | 40 + src/coreclr/src/vm/methodtable.h | 11 + .../CovariantReturns/Interfaces/UnitTest.il | 1138 +++++++++++++++++ .../Interfaces/UnitTest.ilproj | 10 + .../Interfaces/UnsupportedScenario1.il | 318 +++++ .../Interfaces/UnsupportedScenario1.ilproj | 10 + .../Interfaces/UnsupportedScenario2.il | 319 +++++ .../Interfaces/UnsupportedScenario2.ilproj | 10 + 9 files changed, 1860 insertions(+) create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.ilproj create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario2.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario2.ilproj diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index d3d9cde85b3c01..286aa79380f2aa 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -1094,6 +1094,8 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) // Step 2: propate overriding MethodImpls to applicable vtable slots if the declaring method has the attribute + MethodTable::MethodDataWrapper hMTData(MethodTable::GetMethodData(pMT, FALSE)); + for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++) { MethodDesc* pMD = pMT->GetMethodDescForSlot(i); @@ -1138,6 +1140,8 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) // presence of the attribute. pMT->SetSlot(j, pMT->GetSlot(i)); _ASSERT(pMT->GetMethodDescForSlot(j) == pMD); + + hMTData->UpdateImplMethodDesc(pMD, j); } } } diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 1706f0c327c4e4..6bf9d8e0186a0b 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -8468,6 +8468,46 @@ MethodDesc *MethodTable::MethodDataObject::GetImplMethodDesc(UINT32 slotNumber) return pMDRet; } +//========================================================================================== +void MethodTable::MethodDataObject::UpdateImplMethodDesc(MethodDesc* pMD, UINT32 slotNumber) +{ + WRAPPER_NO_CONTRACT; + _ASSERTE(slotNumber < GetNumVirtuals()); + _ASSERTE(pMD->IsMethodImpl()); + +#if _DEBUG + // This kind of update to a vtable slot with a MethodImpl is used when the RequireMethodImplToRemainInEffect attribute is + // applied to the method. Verify this, otherwise we should not be making this kind of update + + bool foundAttribute = false; + MethodTable* pCurrentMT = pMD->GetMethodTable(); + while (!foundAttribute && pCurrentMT != NULL && slotNumber < pCurrentMT->GetNumVirtuals()) + { + MethodDesc* pCurrentMD = pCurrentMT->GetMethodDescForSlot(slotNumber); + + // The attribute is only applicable to MethodImpls. For anything else, it will be treated as a no-op + if (pCurrentMD->IsMethodImpl()) + { + BYTE* pVal = NULL; + ULONG cbVal = 0; + if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::RequireMethodImplToRemainInEffectAttribute, (const void**)&pVal, &cbVal) == S_OK) + foundAttribute = true; + } + + pCurrentMT = pCurrentMT->GetParentMethodTable(); + } + //_ASSERTE(foundAttribute); +#endif + + MethodDataObjectEntry* pEntry = GetEntry(slotNumber); + + // Fill the entries one level of inheritance at a time, + // stopping when we have filled the MD we are looking for. + while (!pEntry->GetImplMethodDesc() && PopulateNextLevel()); + + pEntry->SetImplMethodDesc(pMD); +} + //========================================================================================== void MethodTable::MethodDataObject::InvalidateCachedVirtualSlot(UINT32 slotNumber) { diff --git a/src/coreclr/src/vm/methodtable.h b/src/coreclr/src/vm/methodtable.h index f5aa74556ef28f..a7f6f65168b3bf 100644 --- a/src/coreclr/src/vm/methodtable.h +++ b/src/coreclr/src/vm/methodtable.h @@ -3163,6 +3163,8 @@ public : virtual UINT32 GetNumVirtuals() = 0; virtual UINT32 GetNumMethods() = 0; + virtual void UpdateImplMethodDesc(MethodDesc* pMD, UINT32 slotNumber) = 0; + protected: static const UINT32 INVALID_SLOT_NUMBER = UINT32_MAX; @@ -3267,6 +3269,8 @@ public : virtual UINT32 GetNumMethods() { LIMITED_METHOD_CONTRACT; return m_pDeclMT->GetCanonicalMethodTable()->GetNumMethods(); } + virtual void UpdateImplMethodDesc(MethodDesc* pMD, UINT32 slotNumber); + protected: void Init(MethodData *pParentData); @@ -3373,6 +3377,10 @@ public : { LIMITED_METHOD_CONTRACT; return m_pDeclMT->GetNumVirtuals(); } virtual UINT32 GetNumMethods() { LIMITED_METHOD_CONTRACT; return m_pDeclMT->GetNumMethods(); } + + virtual void UpdateImplMethodDesc(MethodDesc* pMD, UINT32 slotNumber) + { LIMITED_METHOD_CONTRACT; } + }; // class MethodDataInterface //-------------------------------------------------------------------------------------- @@ -3412,6 +3420,9 @@ public : virtual UINT32 GetNumMethods() { WRAPPER_NO_CONTRACT; return m_pDecl->GetNumVirtuals(); } + virtual void UpdateImplMethodDesc(MethodDesc* pMD, UINT32 slotNumber) + { LIMITED_METHOD_CONTRACT; } + protected: UINT32 MapToImplSlotNumber(UINT32 slotNumber); diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il new file mode 100644 index 00000000000000..95d9d4bc8e1089 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il @@ -0,0 +1,1138 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly UnitTest { } + +// ======================================================================================== +// 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, IUnused1 { } +.class interface public auto ansi abstract IB implements IUnused1, IUnused1, IA { } +.class interface public auto ansi abstract IC implements IUnused1, IUnused1, IB { } + +.class interface public auto ansi abstract IGenRetType { } +.class interface public auto ansi abstract IDictionary { } + +.class interface public auto ansi abstract IGenDerive1 implements IUnused1, IUnused1, class IGenRetType { } +.class interface public auto ansi abstract IGenDerive2 implements IUnused1, IUnused1, class IGenDerive1> { } +.class interface public auto ansi abstract IGenDerive3 implements IUnused1, IUnused1, class IGenDerive2 { } + +.class interface public auto ansi abstract INonGenericDerived1 implements IUnused1, IUnused1, class IGenRetType { } +.class interface public auto ansi abstract INonGenericDerived2 implements IUnused1, IUnused1, class INonGenericDerived1 { } +.class interface public auto ansi abstract INonGenericDerived3 implements IUnused1, IUnused1, class INonGenericDerived2 { } +.class interface public auto ansi abstract INonGenericDerived4 implements IUnused1, IUnused1, INonGenericDerived3 { } + +.class interface public auto ansi abstract IGenToNonGen1 implements IUnused1, IUnused1, IC { } +.class interface public auto ansi abstract IGenToNonGen2 implements IUnused1, IUnused1, class IGenToNonGen1> { } +.class interface public auto ansi abstract IGenToNonGen3 implements IUnused1, IUnused1, class IGenToNonGen2 { } + +.class interface public auto ansi abstract INonGenThroughGen1 implements IUnused1, IUnused1, IC { } +.class interface public auto ansi abstract INonGenThroughGen2 implements IUnused1, IUnused1, class INonGenThroughGen1> { } +.class interface public auto ansi abstract INonGenThroughGen3 implements IUnused1, IUnused1, class INonGenThroughGen2 { } +.class interface public auto ansi abstract INonGenThroughGen4 implements IUnused1, IUnused1, INonGenThroughGen3 { } + +// class implementing the interfaces +.class public auto ansi beforefieldinit NonGenThroughGen4 implements IUnused1, IUnused1, INonGenThroughGen4 { } +.class public auto ansi beforefieldinit GenToNonGen3 implements IUnused1, IUnused1, class IGenToNonGen3 { } +.class public auto ansi beforefieldinit NonGenericDerived4 implements IUnused1, IUnused1, INonGenericDerived4 { } +.class public auto ansi beforefieldinit GenDerive3 implements IUnused1, IUnused1, class IGenDerive3 { } +.class public auto ansi beforefieldinit C implements IUnused1, IUnused1, IC { } +.class public auto ansi beforefieldinit GenRetType implements IUnused1, IUnused2, class IGenRetType { } + +// ======================================================================================== +// Main base type with various virtual methods that will be overriden 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 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 + newobj instance void class IGenRetType::.ctor() + ret + } + .method public hidebysig newslot virtual instance class IGenRetType> MyGenFunc(string& res) + { + ldarg.1 + ldstr "IGenRetType> GenBaseType.MyGenFunc()" + 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.RequireMethodImplToRemainInEffectAttribute::.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.RequireMethodImplToRemainInEffectAttribute::.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.RequireMethodImplToRemainInEffectAttribute::.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.RequireMethodImplToRemainInEffectAttribute::.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.RequireMethodImplToRemainInEffectAttribute::.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.RequireMethodImplToRemainInEffectAttribute::.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 + } + + // ======================================================================================== + // 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 + } +} + +// ======================================================================================== +// 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 + } +} + + +// ======================================================================================== +// 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 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 GenTestType ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenMiddleType with covariant returns (when applicable) + // 3) The signature from GenTestType with covariant returns + // And verify that the override on GetTestType is the one that executes + + .method public static bool RunTest1() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance object class GenBaseType::MyFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class IGenRetType class GenTestType::MyFunc(string&) + pop + + ldstr "IGenRetType TestType.MyFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest2() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class IB class GenBaseType::MyFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class IC class GenTestType::MyFunc(string&) + pop + + ldstr "IC TestType.MyFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest3() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class IGenRetType> class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class IGenDerive1> class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class IGenDerive3 class GenTestType::MyGenFunc(string&) + pop + + ldstr "IGenDerive3 TestType.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest4() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class IGenRetType class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class INonGenericDerived1 class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class INonGenericDerived4 class GenTestType::MyGenFunc(string&) + pop + + ldstr "INonGenericDerived4 TestType.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest5() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class IB class GenBaseType::GenToNonGen(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class IGenToNonGen1> class GenMiddleType::GenToNonGen(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class IGenToNonGen3 class GenTestType::GenToNonGen(string&) + pop + + ldstr "IGenToNonGen3 TestType.GenToNonGen()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest6() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class IB class GenBaseType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class INonGenThroughGen2 class GenMiddleType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 2 + callvirt instance class INonGenThroughGen4 class GenTestType::NonGenThroughGenFunc(string&) + pop + + ldstr "INonGenThroughGen4 TestType.NonGenThroughGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + + // ============== Test using GenMiddleType ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenMiddleType with covariant returns + // And verify that the override on GenMiddleType is the one that executes + + .method public static bool RunTest_Middle1() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class IGenRetType> class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class IGenDerive1> class GenMiddleType::MyGenFunc(string&) + pop + + ldstr "IGenDerive1> GenMiddleType.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_Middle2() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class IGenRetType class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class INonGenericDerived1 class GenMiddleType::MyGenFunc(string&) + pop + + ldstr "INonGenericDerived1 GenMiddleType.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_Middle3() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class IB class GenBaseType::GenToNonGen(string&) + pop + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class IGenToNonGen1> class GenMiddleType::GenToNonGen(string&) + pop + + ldstr "IGenToNonGen1> GenMiddleType.GenToNonGen()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_Middle4() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 0 + callvirt instance class IB class GenBaseType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class GenMiddleType::.ctor() + ldloca.s 1 + callvirt instance class INonGenThroughGen2 class GenMiddleType::NonGenThroughGenFunc(string&) + pop + + ldstr "INonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + // ============== Test using GenMoreDerived ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenMiddleType with covariant returns (when applicable) + // 3) The signature from GenTestType with covariant returns + // 4) The signature from GenMoreDerived with covariant returns + // And verify that the override on GenMoreDerived is the one that executes + + .method public static bool RunTest_MoreDerived1() noinlining + { + .locals init (string res1, string res2, string res3, string res4) + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 0 + callvirt instance object class GenBaseType::MyFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 1 + callvirt instance class IGenRetType class GenTestType::MyFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 2 + callvirt instance class GenRetType class GenMoreDerived::MyFunc(string&) + pop + + ldstr "class GenRetType GenMoreDerived.MyFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_MoreDerived2() noinlining + { + .locals init (string res1, string res2, string res3, string res4) + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 0 + callvirt instance class IB class GenBaseType::MyFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 1 + callvirt instance class IC class GenTestType::MyFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 2 + callvirt instance class C class GenMoreDerived::MyFunc(string&) + pop + + ldstr "class C GenMoreDerived.MyFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_MoreDerived3() noinlining + { + .locals init (string res1, string res2, string res3, string res4) + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 0 + callvirt instance class IGenRetType> class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 1 + callvirt instance class IGenDerive1> class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 2 + callvirt instance class IGenDerive3 class GenTestType::MyGenFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 3 + callvirt instance class GenDerive3 class GenMoreDerived::MyGenFunc(string&) + pop + + ldstr "class GenDerive3 GenMoreDerived.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_MoreDerived4() noinlining + { + .locals init (string res1, string res2, string res3, string res4) + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 0 + callvirt instance class IGenRetType class GenBaseType::MyGenFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 1 + callvirt instance class INonGenericDerived1 class GenMiddleType::MyGenFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 2 + callvirt instance class INonGenericDerived4 class GenTestType::MyGenFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 3 + callvirt instance class NonGenericDerived4 class GenMoreDerived::MyGenFunc(string&) + pop + + ldstr "class NonGenericDerived4 GenMoreDerived.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_MoreDerived5() noinlining + { + .locals init (string res1, string res2, string res3, string res4) + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 0 + callvirt instance class IB class GenBaseType::GenToNonGen(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 1 + callvirt instance class IGenToNonGen1> class GenMiddleType::GenToNonGen(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 2 + callvirt instance class IGenToNonGen3 class GenTestType::GenToNonGen(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 3 + callvirt instance class GenToNonGen3 class GenMoreDerived::GenToNonGen(string&) + pop + + ldstr "class GenToNonGen3 GenMoreDerived.GenToNonGen()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest_MoreDerived6() noinlining + { + .locals init (string res1, string res2, string res3, string res4) + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 0 + callvirt instance class IB class GenBaseType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 1 + callvirt instance class INonGenThroughGen2 class GenMiddleType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 2 + callvirt instance class INonGenThroughGen4 class GenTestType::NonGenThroughGenFunc(string&) + pop + + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 3 + callvirt instance class NonGenThroughGen4 class GenMoreDerived::NonGenThroughGenFunc(string&) + pop + + ldstr "class NonGenThroughGen4 GenMoreDerived.NonGenThroughGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldloc.3 + call bool CMain::CheckResults(string,string,string,string,string) + 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 hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + T1: + call bool CMain::RunTest1() + brtrue.s T2 + ldc.i4.0 + stloc.0 + + T2: + call bool CMain::RunTest2() + brtrue.s T3 + ldc.i4.0 + stloc.0 + + T3: + call bool CMain::RunTest3() + brtrue.s T4 + ldc.i4.0 + stloc.0 + + T4: + call bool CMain::RunTest4() + brtrue.s T5 + ldc.i4.0 + stloc.0 + + T5: + call bool CMain::RunTest5() + brtrue.s T6 + ldc.i4.0 + stloc.0 + + T6: + call bool CMain::RunTest6() + brtrue.s M1 + ldc.i4.0 + stloc.0 + + // ===================================================================================== // + + M1: + call bool CMain::RunTest_Middle1() + brtrue.s M2 + ldc.i4.0 + stloc.0 + + M2: + call bool CMain::RunTest_Middle2() + brtrue.s M3 + ldc.i4.0 + stloc.0 + + M3: + call bool CMain::RunTest_Middle3() + brtrue.s M4 + ldc.i4.0 + stloc.0 + + M4: + call bool CMain::RunTest_Middle4() + brtrue.s MOREDERIVED1 + ldc.i4.0 + stloc.0 + + // ===================================================================================== // + + MOREDERIVED1: + call bool CMain::RunTest_MoreDerived1() + brtrue.s MOREDERIVED2 + ldc.i4.0 + stloc.0 + + MOREDERIVED2: + call bool CMain::RunTest_MoreDerived2() + brtrue.s MOREDERIVED3 + ldc.i4.0 + stloc.0 + + MOREDERIVED3: + call bool CMain::RunTest_MoreDerived3() + brtrue.s MOREDERIVED4 + ldc.i4.0 + stloc.0 + + MOREDERIVED4: + call bool CMain::RunTest_MoreDerived4() + brtrue.s MOREDERIVED5 + ldc.i4.0 + stloc.0 + + MOREDERIVED5: + call bool CMain::RunTest_MoreDerived5() + brtrue.s MOREDERIVED6 + ldc.i4.0 + stloc.0 + + MOREDERIVED6: + call bool CMain::RunTest_MoreDerived6() + brtrue.s INVALID1 + 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 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/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.ilproj new file mode 100644 index 00000000000000..921b93a2356ead --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.il new file mode 100644 index 00000000000000..401d993897e7e9 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.il @@ -0,0 +1,318 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Test to validate the current unsupported scenarios will throw a TypeLoadException. +// Scenario being tested here: covariant returns on MethodImpls to interface methods + +.assembly extern System.Console { } +.assembly extern mscorlib { } +.assembly UnsupportedScenario2 { } + +.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 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 class 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 interface public auto ansi abstract BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType MyFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenericDerived4 GenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenDerive3 GenFunc() + { + ldnull + ret + } +} + +.class public auto ansi beforefieldinit Test1 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride() + { + .override method instance class NonGenThroughGen4 class BaseTest::NonGenThroughGenFunc() + ldnull + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +.class public auto ansi beforefieldinit Test2 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class B GenToNonGenOverride() + { + .override method instance class GenToNonGen3 class BaseTest::GenToNonGenFunc() + ldnull + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +.class public auto ansi beforefieldinit Test3 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1() + { + .override method instance class NonGenericDerived4 class BaseTest::GenFunc() + ldnull + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +.class public auto ansi beforefieldinit Test4 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2() + { + .override method instance class GenDerive3 class BaseTest::GenFunc() + ldnull + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +.class public auto ansi beforefieldinit Test5 implements class BaseTest +{ + .method public hidebysig newslot virtual instance object NewFunc1() + { + .override method instance class GenRetType class BaseTest::MyFunc() + ldnull + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } +} + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + newobj instance void class Test1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + newobj instance void class Test2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + newobj instance void class Test3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + newobj instance void class Test4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + newobj instance void class Test5::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." + call void [System.Console]System.Console::WriteLine(string) + leave.s T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." + call void [System.Console]System.Console::WriteLine(string) + leave.s T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." + call void [System.Console]System.Console::WriteLine(string) + leave.s T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." + call void [System.Console]System.Console::WriteLine(string) + leave.s T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method CMain::.ctor + +} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.ilproj new file mode 100644 index 00000000000000..01b74f71e93043 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario2.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario2.il new file mode 100644 index 00000000000000..d87cd8bb22ea5e --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario2.il @@ -0,0 +1,319 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Test to validate the current unsupported scenarios will throw a TypeLoadException. +// Scenario being tested here: covariant returns on default interface methods. + +.assembly extern System.Console { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly UnsupportedScenario2 { } + +.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 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 class 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 interface public auto ansi abstract BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType MyFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenericDerived4 GenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenDerive3 GenFunc() + { + ldnull + ret + } +} + +.class interface public auto ansi abstract Test1 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride() + { + .override method instance class NonGenThroughGen4 class BaseTest::NonGenThroughGenFunc() + ldnull + ret + } +} + +.class interface public auto ansi abstract Test2 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class B GenToNonGenOverride() + { + .override method instance class GenToNonGen3 class BaseTest::GenToNonGenFunc() + ldnull + ret + } +} + +.class interface public auto ansi abstract Test3 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1() + { + .override method instance class NonGenericDerived4 class BaseTest::GenFunc() + ldnull + ret + } +} + +.class interface public auto ansi abstract Test4 implements class BaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2() + { + .override method instance class GenDerive3 class BaseTest::GenFunc() + ldnull + ret + } +} + +.class interface public auto ansi abstract Test5 implements class BaseTest +{ + .method public hidebysig newslot virtual instance object NewFunc1() + { + .override method instance class GenRetType class BaseTest::MyFunc() + ldnull + ret + } +} + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + ldtoken class Test1 + call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + ldtoken class Test2 + call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + ldtoken class Test3 + call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + ldtoken class Test4 + call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + ldtoken class Test5 + call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle) + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." + call void [System.Console]System.Console::WriteLine(string) + leave.s T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." + call void [System.Console]System.Console::WriteLine(string) + leave.s T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." + call void [System.Console]System.Console::WriteLine(string) + leave.s T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." + call void [System.Console]System.Console::WriteLine(string) + leave.s T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method CMain::.ctor + +} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario2.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario2.ilproj new file mode 100644 index 00000000000000..7e95e6b070bbcc --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario2.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + From 5a85da8ca89ba743a24a0c719cb782b02917bbf3 Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Thu, 30 Apr 2020 12:31:57 -0700 Subject: [PATCH 09/21] Handling for struct cases, and adding test coverage for it. --- .../features/covariant-return-methods.md | 4 +- src/coreclr/src/vm/class.cpp | 5 +- src/coreclr/src/vm/methodtable.cpp | 24 - .../CovariantReturns/Interfaces/UnitTest.il | 44 +- .../Interfaces/UnsupportedScenario1.il | 25 +- .../Interfaces/UnsupportedScenario3.il | 346 +++++++++++++ .../UnsupportedScenario3.ilproj} | 2 +- .../Structs/IncompatibleOverride.il | 344 +++++++++++++ .../Structs/IncompatibleOverride.ilproj | 10 + .../UnitTest/UnitTestDelegates.il | 482 ------------------ 10 files changed, 743 insertions(+), 543 deletions(-) create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario3.il rename src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/{UnitTest/UnitTestDelegates.ilproj => Interfaces/UnsupportedScenario3.ilproj} (82%) create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.ilproj delete mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il diff --git a/docs/design/features/covariant-return-methods.md b/docs/design/features/covariant-return-methods.md index 8bf067d698414a..dd7a1d28d47222 100644 --- a/docs/design/features/covariant-return-methods.md +++ b/docs/design/features/covariant-return-methods.md @@ -2,7 +2,7 @@ Covariant return methods is a runtime feature designed to support the [covariant return types](https://github.com/dotnet/csharplang/blob/master/proposals/covariant-returns.md) and [records](https://github.com/dotnet/csharplang/blob/master/proposals/records.md) C# language features posed for C# 9.0. -This feature allows an overriding method to have a return type that is different than the one on the method it overrides, but compatible with it. The type compability rules are defined in ECMA I.8.7.1. Example: using a more derived return type. The only exception applicable to this rule for this feature is the compatibility between a value type and an interface that it implements, and this is due to the difference in ABI between reference types and value types (unboxed value types can be returned through a hidden return buffer parameter). +This feature allows an overriding method to have a return type that is different than the one on the method it overrides, but compatible with it. The type compability rules are defined in ECMA I.8.7.1. Example: using a more derived return type. Covariant return methods can only be described through MethodImpl records, and as an initial implementation will only be applicable to methods on reference types. Methods on interfaces and value types will not be supported (may be supported later in the future). @@ -25,6 +25,8 @@ During enumeration of MethodImpls on a type (`MethodTableBuilder::EnumerateMetho + Load the `TypeHandle` of the return type of the method on the current type being validated. + Verify that the second `TypeHandle` is compatible with the first `TypeHandle` using the `MethodTable::CanCastTo()` API. If they are not compatible, a TypeLoadException is thrown. +The only exception where `CanCastTo()` will return true for an incompatible type according to the ECMA rules is for structs implementing interfaces, so we explicitly check for that case and throw a TypeLoadException if we hit it. + Once a method is flagged for return type checking, every time the vtable slot containing that method gets overridden on a derived type, the new override will also be checked for compatiblity. This is to ensure that no derived type can implicitly override some virtual method that has already been overridden by some MethodImpl with a covariant return type. ### VTable Slot Unification diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index 286aa79380f2aa..3cf54297fd806c 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -1066,8 +1066,11 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) { GCX_COOP(); + // Structs can be casted to the interfaces they implement, but they are not compatible according to ECMA I.8.7.1 + bool isCastFromValueTypeToReferenceType = hType2.IsValueType() && !hType1.IsValueType(); + TypeHandlePairList visited(hType1, hType2, NULL); - if (!hType2.GetMethodTable()->CanCastTo(hType1.GetMethodTable(), &visited)) + if (isCastFromValueTypeToReferenceType || !hType2.GetMethodTable()->CanCastTo(hType1.GetMethodTable(), &visited)) { SString strAssemblyName; pMD->GetAssembly()->GetDisplayName(strAssemblyName); diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 6bf9d8e0186a0b..4269f69720b7f5 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -8475,30 +8475,6 @@ void MethodTable::MethodDataObject::UpdateImplMethodDesc(MethodDesc* pMD, UINT32 _ASSERTE(slotNumber < GetNumVirtuals()); _ASSERTE(pMD->IsMethodImpl()); -#if _DEBUG - // This kind of update to a vtable slot with a MethodImpl is used when the RequireMethodImplToRemainInEffect attribute is - // applied to the method. Verify this, otherwise we should not be making this kind of update - - bool foundAttribute = false; - MethodTable* pCurrentMT = pMD->GetMethodTable(); - while (!foundAttribute && pCurrentMT != NULL && slotNumber < pCurrentMT->GetNumVirtuals()) - { - MethodDesc* pCurrentMD = pCurrentMT->GetMethodDescForSlot(slotNumber); - - // The attribute is only applicable to MethodImpls. For anything else, it will be treated as a no-op - if (pCurrentMD->IsMethodImpl()) - { - BYTE* pVal = NULL; - ULONG cbVal = 0; - if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::RequireMethodImplToRemainInEffectAttribute, (const void**)&pVal, &cbVal) == S_OK) - foundAttribute = true; - } - - pCurrentMT = pCurrentMT->GetParentMethodTable(); - } - //_ASSERTE(foundAttribute); -#endif - MethodDataObjectEntry* pEntry = GetEntry(slotNumber); // Fill the entries one level of inheritance at a time, diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il index 95d9d4bc8e1089..ec48134ab6ec90 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il @@ -14,37 +14,37 @@ .class interface public auto ansi abstract IUnused1 { } .class interface public auto ansi abstract IUnused2 { } -.class interface public auto ansi abstract IA implements IUnused1, IUnused1 { } -.class interface public auto ansi abstract IB implements IUnused1, IUnused1, IA { } -.class interface public auto ansi abstract IC implements IUnused1, IUnused1, IB { } +.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 interface public auto ansi abstract IGenDerive1 implements IUnused1, IUnused1, class IGenRetType { } -.class interface public auto ansi abstract IGenDerive2 implements IUnused1, IUnused1, class IGenDerive1> { } -.class interface public auto ansi abstract IGenDerive3 implements IUnused1, IUnused1, class IGenDerive2 { } +.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, IUnused1, class IGenRetType { } -.class interface public auto ansi abstract INonGenericDerived2 implements IUnused1, IUnused1, class INonGenericDerived1 { } -.class interface public auto ansi abstract INonGenericDerived3 implements IUnused1, IUnused1, class INonGenericDerived2 { } -.class interface public auto ansi abstract INonGenericDerived4 implements IUnused1, IUnused1, INonGenericDerived3 { } +.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, IUnused1, IC { } -.class interface public auto ansi abstract IGenToNonGen2 implements IUnused1, IUnused1, class IGenToNonGen1> { } -.class interface public auto ansi abstract IGenToNonGen3 implements IUnused1, IUnused1, class IGenToNonGen2 { } +.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, IUnused1, IC { } -.class interface public auto ansi abstract INonGenThroughGen2 implements IUnused1, IUnused1, class INonGenThroughGen1> { } -.class interface public auto ansi abstract INonGenThroughGen3 implements IUnused1, IUnused1, class INonGenThroughGen2 { } -.class interface public auto ansi abstract INonGenThroughGen4 implements IUnused1, IUnused1, INonGenThroughGen3 { } +.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, IUnused1, INonGenThroughGen4 { } -.class public auto ansi beforefieldinit GenToNonGen3 implements IUnused1, IUnused1, class IGenToNonGen3 { } -.class public auto ansi beforefieldinit NonGenericDerived4 implements IUnused1, IUnused1, INonGenericDerived4 { } -.class public auto ansi beforefieldinit GenDerive3 implements IUnused1, IUnused1, class IGenDerive3 { } -.class public auto ansi beforefieldinit C implements IUnused1, IUnused1, IC { } +.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 { } // ======================================================================================== diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.il index 401d993897e7e9..e87a43202c7ca1 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario1.il @@ -3,7 +3,8 @@ // See the LICENSE file in the project root for more information. // Test to validate the current unsupported scenarios will throw a TypeLoadException. -// Scenario being tested here: covariant returns on MethodImpls to interface methods +// Scenario being tested here: covariant returns on MethodImpls to interface methods +// implemented by classes .assembly extern System.Console { } .assembly extern mscorlib { } @@ -73,7 +74,7 @@ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } -.class interface public auto ansi abstract BaseTest +.class interface public auto ansi abstract IBaseTest { .method public hidebysig newslot virtual instance class GenRetType MyFunc() { @@ -102,55 +103,55 @@ } } -.class public auto ansi beforefieldinit Test1 implements class BaseTest +.class public auto ansi beforefieldinit Test1 implements class IBaseTest { .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride() { - .override method instance class NonGenThroughGen4 class BaseTest::NonGenThroughGenFunc() + .override method instance class NonGenThroughGen4 class IBaseTest::NonGenThroughGenFunc() ldnull ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } -.class public auto ansi beforefieldinit Test2 implements class BaseTest +.class public auto ansi beforefieldinit Test2 implements class IBaseTest { .method public hidebysig newslot virtual instance class B GenToNonGenOverride() { - .override method instance class GenToNonGen3 class BaseTest::GenToNonGenFunc() + .override method instance class GenToNonGen3 class IBaseTest::GenToNonGenFunc() ldnull ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } -.class public auto ansi beforefieldinit Test3 implements class BaseTest +.class public auto ansi beforefieldinit Test3 implements class IBaseTest { .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1() { - .override method instance class NonGenericDerived4 class BaseTest::GenFunc() + .override method instance class NonGenericDerived4 class IBaseTest::GenFunc() ldnull ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } -.class public auto ansi beforefieldinit Test4 implements class BaseTest +.class public auto ansi beforefieldinit Test4 implements class IBaseTest { .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2() { - .override method instance class GenDerive3 class BaseTest::GenFunc() + .override method instance class GenDerive3 class IBaseTest::GenFunc() ldnull ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } } -.class public auto ansi beforefieldinit Test5 implements class BaseTest +.class public auto ansi beforefieldinit Test5 implements class IBaseTest { .method public hidebysig newslot virtual instance object NewFunc1() { - .override method instance class GenRetType class BaseTest::MyFunc() + .override method instance class GenRetType class IBaseTest::MyFunc() ldnull ret } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario3.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario3.il new file mode 100644 index 00000000000000..78a75da9080680 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario3.il @@ -0,0 +1,346 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Test to validate the current unsupported scenarios will throw a TypeLoadException. +// Scenario being tested here: covariant returns on MethodImpls to interface methods +// implemented by structs + +.assembly extern System.Console { } +.assembly extern mscorlib { } +.assembly UnsupportedScenario3 { } + +.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 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 class 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 interface public auto ansi abstract IBaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType MyFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class NonGenericDerived4 GenFunc() + { + ldnull + ret + } + .method public hidebysig newslot virtual instance class GenDerive3 GenFunc() + { + ldnull + ret + } +} + +.class public sealed auto ansi Test1 + extends [mscorlib]System.ValueType + implements class IBaseTest +{ + .method public hidebysig newslot virtual instance class B NonGenThroughGenOverride() + { + .override method instance class NonGenThroughGen4 class IBaseTest::NonGenThroughGenFunc() + ldnull + ret + } +} + +.class public sealed auto ansi Test2 + extends [mscorlib]System.ValueType + implements class IBaseTest +{ + .method public hidebysig newslot virtual instance class B GenToNonGenOverride() + { + .override method instance class GenToNonGen3 class IBaseTest::GenToNonGenFunc() + ldnull + ret + } +} + +.class public sealed auto ansi Test3 + extends [mscorlib]System.ValueType + implements class IBaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType NewGenFunc1() + { + .override method instance class NonGenericDerived4 class IBaseTest::GenFunc() + ldnull + ret + } +} + +.class public sealed auto ansi Test4 + extends [mscorlib]System.ValueType + implements class IBaseTest +{ + .method public hidebysig newslot virtual instance class GenRetType> NewGenFunc2() + { + .override method instance class GenDerive3 class IBaseTest::GenFunc() + ldnull + ret + } +} + +.class public sealed auto ansi Test5 + extends [mscorlib]System.ValueType + implements class IBaseTest +{ + .method public hidebysig newslot virtual instance object NewFunc1() + { + .override method instance class GenRetType class IBaseTest::MyFunc() + ldnull + ret + } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + .locals init (valuetype Test1) + ldloca.s 0 + initobj valuetype Test1 + ldloc.0 + box valuetype Test1 + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + .locals init (valuetype Test2) + ldloca.s 0 + initobj valuetype Test2 + ldloc.0 + box valuetype Test2 + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + .locals init (valuetype Test3) + ldloca.s 0 + initobj valuetype Test3 + ldloc.0 + box valuetype Test3 + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + .locals init (valuetype Test4) + ldloca.s 0 + initobj valuetype Test4 + ldloc.0 + box valuetype Test4 + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + .locals init (valuetype Test5) + ldloca.s 0 + initobj valuetype Test5 + ldloc.0 + box valuetype Test5 + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." + call void [System.Console]System.Console::WriteLine(string) + leave.s T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." + call void [System.Console]System.Console::WriteLine(string) + leave.s T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." + call void [System.Console]System.Console::WriteLine(string) + leave.s T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." + call void [System.Console]System.Console::WriteLine(string) + leave.s T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method CMain::.ctor + +} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario3.ilproj similarity index 82% rename from src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj rename to src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario3.ilproj index 1667d3b14ac0ba..a182efdb3bb629 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnsupportedScenario3.ilproj @@ -5,6 +5,6 @@ 0 - + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.il new file mode 100644 index 00000000000000..04657d69db8cd2 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.il @@ -0,0 +1,344 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// +// Invalid scenario verification: overriding a base type method returning an interface type +// with a MethodImpl that returns a struct implementing that interface should throw: +// struct is castable to the interface it implements, but not compatible with it. +// + +.assembly extern System.Console { } +.assembly extern mscorlib { } +.assembly IncompatibleOverride { } + + +// ======================================================================================== +// Types that will be used as return types on the various methods +// ======================================================================================== + +.class interface public auto ansi abstract IA { } +.class interface public auto ansi abstract IGenRetType { } +.class interface public auto ansi abstract IDictionary { } + +.class interface public auto ansi abstract IB implements IA { } +.class interface public auto ansi abstract IGenDerive implements class IGenRetType { } + +// Structs implementing the interfaces +.class public sealed auto ansi A extends [mscorlib]System.ValueType + implements IA { } + +.class public sealed auto ansi B extends [mscorlib]System.ValueType + implements IB { } + +.class public sealed auto ansi RetType extends [mscorlib]System.ValueType + implements class IGenRetType { } + +.class public sealed auto ansi DerivedRetType extends [mscorlib]System.ValueType + implements class IGenDerive { } + +.class public sealed auto ansi GenRetType extends [mscorlib]System.ValueType + implements class IGenRetType> { } + +.class public sealed auto ansi DerivedGenRetType extends [mscorlib]System.ValueType + implements class IGenDerive> { } + +// ======================================================================================== +// Main base type with various virtual methods that will be overriden later +// ======================================================================================== + +.class public auto ansi beforefieldinit GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class IA NonGen(string& res) + { + ldarg.1 + ldstr "IA GenBaseType.NonGen()" + stind.ref + ldnull + ret + } + .method public hidebysig newslot virtual instance class IGenRetType GenFunc(string& res) + { + ldarg.1 + ldstr "IGenRetType GenBaseType.GenFunc()" + stind.ref + newobj instance void class IGenRetType::.ctor() + ret + } + .method public hidebysig newslot virtual instance class IGenRetType> GenFunc(string& res) + { + ldarg.1 + ldstr "IGenRetType> GenBaseType.GenFunc()" + stind.ref + ldnull + ret + } +} + +// ======================================================================================== +// INVALID TYPES: override base type methods and return structs implementing the return type +// interfaces of the overridden methods. +// ======================================================================================== + + +.class public auto ansi beforefieldinit Invalid1 extends class GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance valuetype A NonGen(string& res) + { + .override method instance class IA class GenBaseType::NonGen(string& res) + .locals ( valuetype A ) + ldloc.0 + ret + } +} + +.class public auto ansi beforefieldinit Invalid2 extends class GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance valuetype B NonGen(string& res) + { + .override method instance class IA class GenBaseType::NonGen(string& res) + .locals ( valuetype B ) + ldloc.0 + ret + } +} + +.class public auto ansi beforefieldinit Invalid3 extends class GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance valuetype RetType GenFunc(string& res) + { + .override method instance class IGenRetType class GenBaseType::GenFunc(string& res) + .locals ( valuetype RetType ) + ldloc.0 + ret + } +} + +.class public auto ansi beforefieldinit Invalid4 extends class GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance valuetype DerivedRetType GenFunc(string& res) + { + .override method instance class IGenRetType class GenBaseType::GenFunc(string& res) + .locals ( valuetype DerivedRetType ) + ldloc.0 + ret + } +} + +.class public auto ansi beforefieldinit Invalid5 extends class GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance valuetype GenRetType GenFunc(string& res) + { + .override method instance class IGenRetType> class GenBaseType::GenFunc(string& res) + .locals ( valuetype GenRetType ) + ldloc.0 + ret + } +} + +.class public auto ansi beforefieldinit Invalid6 extends class GenBaseType +{ + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } + .method public hidebysig newslot virtual instance valuetype DerivedGenRetType GenFunc(string& res) + { + .override method instance class IGenRetType> class GenBaseType::GenFunc(string& res) + .locals ( valuetype DerivedGenRetType ) + ldloc.0 + ret + } +} + +// ======================================================================================== + +.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object +{ + .method public static void RunTest1() noinlining + { + newobj instance void class Invalid1::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest2() noinlining + { + newobj instance void class Invalid2::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest3() noinlining + { + newobj instance void class Invalid3::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest4() noinlining + { + newobj instance void class Invalid4::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest5() noinlining + { + newobj instance void class Invalid5::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public static void RunTest6() noinlining + { + newobj instance void class Invalid6::.ctor() + call void [System.Console]System.Console::WriteLine(object) + ret + } + + .method public hidebysig static int32 Main( string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init (bool V_0) + ldc.i4.1 + stloc.0 + + T1: + .try + { + call void CMain::RunTest1() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test1." + call void [System.Console]System.Console::WriteLine(string) + leave.s T2 + } + 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 T2 + } + + T2: + .try + { + call void CMain::RunTest2() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test2." + call void [System.Console]System.Console::WriteLine(string) + leave.s T3 + } + 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 T3 + } + + T3: + .try + { + call void CMain::RunTest3() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test3." + call void [System.Console]System.Console::WriteLine(string) + leave.s T4 + } + 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 T4 + } + + T4: + .try + { + call void CMain::RunTest4() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test4." + call void [System.Console]System.Console::WriteLine(string) + leave.s T5 + } + 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 T5 + } + + T5: + .try + { + call void CMain::RunTest5() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + call void [System.Console]System.Console::WriteLine(string) + leave.s T6 + } + 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 T6 + } + + T6: + .try + { + call void CMain::RunTest6() + ldc.i4.0 + stloc.0 + ldstr "FAIL: did not catch expected TypeLoadException when loading Test5." + 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 + + ldc.i4.s 101 + ret + + PASS: + ldstr "Test PASSED" + call void [System.Console]System.Console::WriteLine(string) + ldc.i4.s 100 + ret + } + + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method CMain::.ctor + +} // end of class CMain diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.ilproj new file mode 100644 index 00000000000000..cc3de09a7be488 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il deleted file mode 100644 index 5a22dfc541b0d6..00000000000000 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il +++ /dev/null @@ -1,482 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -.assembly extern System.Console { } -.assembly extern System.Runtime { } -.assembly extern mscorlib { } -.assembly UnitTestDelegates { } - -.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 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 GenBaseType -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - 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 - } - .method public hidebysig newslot virtual instance class GenRetType TestNonGenericDerived(string& res) - { - ldarg.1 - ldstr "GenRetType GenBaseType.TestNonGenericDerived()" - stind.ref - newobj instance void class GenRetType::.ctor() - ret - } -} - - - -.class public auto ansi beforefieldinit GenTestType extends class GenBaseType -{ - .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenOverride(string& res) - { - .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) - ldarg.1 - ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenToNonGen3 GenToNonGenOverride(string& res) - { - .override method instance class B class GenBaseType::GenToNonGen(string& res) - ldarg.1 - ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class NonGenericDerived4 NewGenFunc1(string& res) - { - .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) - ldarg.1 - ldstr "NonGenericDerived4 TestType.NewGenFunc1()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenDerive3 NewGenFunc2(string& res) - { - .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) - ldarg.1 - ldstr "GenDerive3 TestType.NewGenFunc2()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class GenRetType NewFunc1(string& res) - { - .override method instance object class GenBaseType::MyFunc(string& res) - ldarg.1 - ldstr "GenRetType TestType.NewFunc1()" - stind.ref - ldnull - ret - } - - .method public hidebysig newslot virtual instance class C NewFunc2(string& res) - { - .override method instance class B class GenBaseType::MyFunc(string& res) - ldarg.1 - ldstr "C TestType.NewFunc2()" - stind.ref - ldnull - ret - } - - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed - { - .maxstack 8 - ldarg.0 - call instance void class GenBaseType::.ctor() - ret - } -} - - - - -.class public auto ansi sealed ReturnObjDel extends [System.Runtime]System.MulticastDelegate -{ - // We can use a delegate with signature 'object Invoke(string&)' for all methods here since they all return a reference type - - .method public hidebysig specialname rtspecialname instance void .ctor (object 'object', native int 'method') runtime managed { } - .method public hidebysig newslot virtual instance class [System.Runtime]System.IAsyncResult BeginInvoke (string& res, class [System.Runtime]System.AsyncCallback callback, object 'object') runtime managed { } - .method public hidebysig newslot virtual instance object Invoke (string& res) runtime managed { } - .method public hidebysig newslot virtual instance object EndInvoke (string& res, class [System.Runtime]System.IAsyncResult result) runtime managed { } -} - -.class public auto ansi beforefieldinit CMain extends [mscorlib]System.Object -{ - .method public static bool RunTest1() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenRetType TestType.NewFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenTestType::.ctor() - dup - ldvirtftn instance object class GenBaseType::MyFunc(string&) - newobj instance void class ReturnObjDel::.ctor(object, native int) - - ldloca.s 0 - callvirt instance object class ReturnObjDel::Invoke(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenRetType TestType.NewFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest2() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: C TestType.NewFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenTestType::.ctor() - dup - ldvirtftn instance class B class GenBaseType::MyFunc(string&) - newobj instance void class ReturnObjDel::.ctor(object, native int) - - ldloca.s 0 - callvirt instance object class ReturnObjDel::Invoke(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "C TestType.NewFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest3() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenDerive3 TestType.NewGenFunc2()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenTestType::.ctor() - dup - ldvirtftn instance class GenRetType> class GenBaseType::MyGenFunc(string&) - newobj instance void class ReturnObjDel::.ctor(object, native int) - - ldloca.s 0 - callvirt instance object class ReturnObjDel::Invoke(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenDerive3 TestType.NewGenFunc2()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest4() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenericDerived4 TestType.NewGenFunc1()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenTestType::.ctor() - dup - ldvirtftn instance class GenRetType class GenBaseType::MyGenFunc(string&) - newobj instance void class ReturnObjDel::.ctor(object, native int) - - ldloca.s 0 - callvirt instance object class ReturnObjDel::Invoke(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenericDerived4 TestType.NewGenFunc1()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest5() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: GenToNonGen3 TestType.GenToNonGenOverride()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenTestType::.ctor() - dup - ldvirtftn instance class B class GenBaseType::GenToNonGen(string&) - newobj instance void class ReturnObjDel::.ctor(object, native int) - - ldloca.s 0 - callvirt instance object class ReturnObjDel::Invoke(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "GenToNonGen3 TestType.GenToNonGenOverride()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public static bool RunTest6() noinlining - { - .locals init (string res, bool flag) - - ldstr "EXPECTED: NonGenThroughGen4 TestType.NonGenThroughGenFunc()" - call void [System.Console]System.Console::WriteLine(object) - ldstr "ACTUAL : " - call void [System.Console]System.Console::Write(object) - - newobj instance void class GenTestType::.ctor() - dup - ldvirtftn instance class B class GenBaseType::NonGenThroughGenFunc(string& res) - newobj instance void class ReturnObjDel::.ctor(object, native int) - - ldloca.s 0 - callvirt instance object class ReturnObjDel::Invoke(string&) - pop - - ldloc.0 - call void [System.Console]System.Console::WriteLine(object) - - ldloc.0 - ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" - call bool [System.Runtime]System.String::op_Equality(string, string) - ret - } - - .method public hidebysig static int32 Main( string[] args) cil managed - { - .entrypoint - .maxstack 2 - .locals init ( bool result ) - - ldc.i4.1 - stloc.0 - - T1: - call bool CMain::RunTest1() - brtrue.s T2 - ldc.i4.0 - stloc.0 - - T2: - call bool CMain::RunTest2() - brtrue.s T3 - ldc.i4.0 - stloc.0 - - T3: - call bool CMain::RunTest3() - brtrue.s T4 - ldc.i4.0 - stloc.0 - - T4: - call bool CMain::RunTest4() - brtrue.s T5 - ldc.i4.0 - stloc.0 - - T5: - call bool CMain::RunTest5() - brtrue.s T6 - ldc.i4.0 - stloc.0 - - T6: - call bool CMain::RunTest6() - brtrue.s DONE - ldc.i4.0 - 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 - } -} From 89bb5c3b5177a55d1f560613650ee5deff6f5426 Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Thu, 30 Apr 2020 13:06:02 -0700 Subject: [PATCH 10/21] Small test fixes --- .../MethodImpl/CovariantReturns/Interfaces/UnitTest.il | 2 +- .../MethodImpl/CovariantReturns/Structs/IncompatibleOverride.il | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il index ec48134ab6ec90..7b0d94d11c5f5b 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il @@ -92,7 +92,7 @@ ldarg.1 ldstr "IGenRetType GenBaseType.MyGenFunc()" stind.ref - newobj instance void class IGenRetType::.ctor() + ldnull ret } .method public hidebysig newslot virtual instance class IGenRetType> MyGenFunc(string& res) diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.il index 04657d69db8cd2..8687088b3b1287 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride.il @@ -64,7 +64,7 @@ ldarg.1 ldstr "IGenRetType GenBaseType.GenFunc()" stind.ref - newobj instance void class IGenRetType::.ctor() + ldnull ret } .method public hidebysig newslot virtual instance class IGenRetType> GenFunc(string& res) From cbecf78daa23c3458bfdad2c34e10ea2da524d9a Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Thu, 30 Apr 2020 15:49:43 -0700 Subject: [PATCH 11/21] Fix consistency issue with the way the RequireMethodImplToRemainInEffectAttribute is declared --- .../RequireMethodImplToRemainInEffectAttribute.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RequireMethodImplToRemainInEffectAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RequireMethodImplToRemainInEffectAttribute.cs index 8ffbf8484b3d07..91d7d2f02f7373 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RequireMethodImplToRemainInEffectAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RequireMethodImplToRemainInEffectAttribute.cs @@ -4,7 +4,7 @@ namespace System.Runtime.CompilerServices { - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] + [AttributeUsageAttribute(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] public sealed class RequireMethodImplToRemainInEffectAttribute : Attribute { } From 1154b90e1f46612386fc049f28d349f48e465ec4 Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Mon, 4 May 2020 15:58:09 -0700 Subject: [PATCH 12/21] Support covariant returns and slot unifications in crossgen2 These changes fix the behavior of the devirtualization algorithm to not incorrectly devirtualize covariant return methods that have the slot unification attribute --- .../MetadataRuntimeInterfacesAlgorithm.cs | 8 +- .../Common/MetadataVirtualMethodAlgorithm.cs | 113 +++++++++++++++--- .../TypeSystem/Common/MethodDesc.ToString.cs | 4 +- .../Common/TypeSystem/Common/MethodDesc.cs | 15 ++- .../TypeSystem/Common/TypeSystemHelpers.cs | 24 ++++ 5 files changed, 139 insertions(+), 25 deletions(-) diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataRuntimeInterfacesAlgorithm.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataRuntimeInterfacesAlgorithm.cs index 4b71985bfbee01..2c5d4789afce54 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataRuntimeInterfacesAlgorithm.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataRuntimeInterfacesAlgorithm.cs @@ -22,13 +22,7 @@ public override DefType[] ComputeRuntimeInterfaces(TypeDesc _type) // TODO: need to implement deduplication // https://github.com/dotnet/corert/issues/208 - if (type.IsInterface) - { - // For interfaces, the set of interfaces implemented directly matches the - // explicitly implemented interface list - return type.ExplicitlyImplementedInterfaces; - } - else if (type is InstantiatedType) + if (type is InstantiatedType) { return ComputeRuntimeInterfacesForInstantiatedType((InstantiatedType)type); } diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs index dbd21a08347675..7f188a89b43a04 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs @@ -45,6 +45,9 @@ private class UnificationGroup private MethodDesc[] _members = MethodDesc.EmptyMethods; private int _memberCount = 0; + private MethodDesc[] _methodsRequiringSlotUnification = MethodDesc.EmptyMethods; + private int _methodsRequiringSlotUnificationCount = 0; + /// /// Custom enumerator struct for Unification group. Makes enumeration require 0 allocations. /// @@ -99,6 +102,42 @@ public Enumerator GetEnumerator() return new Enumerator(_members); } + public IEnumerable MethodsRequiringSlotUnification + { + get + { + foreach (var method in _methodsRequiringSlotUnification) + { + if (method == null) + yield break; + yield return method; + } + } + } + + public void AddMethodRequiringSlotUnification(MethodDesc method) + { + if (RequiresSlotUnification(method)) + return; + + _methodsRequiringSlotUnificationCount++; + if (_methodsRequiringSlotUnificationCount >= _methodsRequiringSlotUnification.Length) + { + Array.Resize(ref _methodsRequiringSlotUnification, Math.Max(_methodsRequiringSlotUnification.Length * 2, 2)); + } + _methodsRequiringSlotUnification[_methodsRequiringSlotUnificationCount - 1] = method; + } + + public bool RequiresSlotUnification(MethodDesc method) + { + for(int i = 0; i < _methodsRequiringSlotUnificationCount; i++) + { + if (_methodsRequiringSlotUnification[i] == method) + return true; + } + return false; + } + public void SetDefiningMethod(MethodDesc newDefiningMethod) { // Do not change the defining method if its the same as @@ -395,6 +434,11 @@ private static void FindBaseUnificationGroup(MetadataType currentType, Unificati MethodDesc methodImpl = FindImplFromDeclFromMethodImpls(currentType, unificationGroup.DefiningMethod); if (methodImpl != null) { + if(methodImpl.RequiresSlotUnification()) + { + unificationGroup.AddMethodRequiringSlotUnification(unificationGroup.DefiningMethod); + unificationGroup.AddMethodRequiringSlotUnification(methodImpl); + } unificationGroup.SetDefiningMethod(methodImpl); } @@ -448,29 +492,68 @@ private static void FindBaseUnificationGroup(MetadataType currentType, Unificati if (separatedMethods == null) separatedMethods = new MethodDescHashtable(); separatedMethods.AddOrGetExisting(declSlot); + + if (unificationGroup.RequiresSlotUnification(declSlot) || implSlot.RequiresSlotUnification()) + { + if (implSlot.Signature.Equals(unificationGroup.DefiningMethod.Signature, true)) + { + unificationGroup.AddMethodRequiringSlotUnification(declSlot); + unificationGroup.AddMethodRequiringSlotUnification(implSlot); + unificationGroup.SetDefiningMethod(implSlot); + } + } + continue; } - if (!unificationGroup.IsInGroupOrIsDefiningSlot(declSlot) && unificationGroup.IsInGroupOrIsDefiningSlot(implSlot)) + if (!unificationGroup.IsInGroupOrIsDefiningSlot(declSlot)) { - // Add decl to group. + if (unificationGroup.IsInGroupOrIsDefiningSlot(implSlot)) + { + // Add decl to group. - // To do so, we need to have the Unification Group of the decl slot, as it may have multiple members itself - UnificationGroup addDeclGroup = new UnificationGroup(declSlot); - FindBaseUnificationGroup(baseType, addDeclGroup); - Debug.Assert(addDeclGroup.IsInGroupOrIsDefiningSlot(declSlot)); + // To do so, we need to have the Unification Group of the decl slot, as it may have multiple members itself + UnificationGroup addDeclGroup = new UnificationGroup(declSlot); + FindBaseUnificationGroup(baseType, addDeclGroup); + Debug.Assert( + addDeclGroup.IsInGroupOrIsDefiningSlot(declSlot) || + (addDeclGroup.RequiresSlotUnification(declSlot) && addDeclGroup.DefiningMethod.Signature.Equals(declSlot.Signature, true))); - // Add all members from the decl's unification group except for ones that have been seperated by name/sig matches - // or previously processed methodimpls. NOTE: This implies that method impls are order dependent. - if (separatedMethods == null || !separatedMethods.Contains(addDeclGroup.DefiningMethod)) - { - unificationGroup.AddToGroup(addDeclGroup.DefiningMethod); - } + foreach(MethodDesc methodImplRequiredToRemainInEffect in addDeclGroup.MethodsRequiringSlotUnification) + { + unificationGroup.AddMethodRequiringSlotUnification(methodImplRequiredToRemainInEffect); + } - foreach (MethodDesc addDeclGroupMemberMethod in addDeclGroup) + // Add all members from the decl's unification group except for ones that have been seperated by name/sig matches + // or previously processed methodimpls. NOTE: This implies that method impls are order dependent. + if (separatedMethods == null || !separatedMethods.Contains(addDeclGroup.DefiningMethod)) + { + unificationGroup.AddToGroup(addDeclGroup.DefiningMethod); + } + + foreach (MethodDesc addDeclGroupMemberMethod in addDeclGroup) + { + if (separatedMethods == null || !separatedMethods.Contains(addDeclGroupMemberMethod)) + { + unificationGroup.AddToGroup(addDeclGroupMemberMethod); + } + } + + if(unificationGroup.RequiresSlotUnification(declSlot)) + { + unificationGroup.AddMethodRequiringSlotUnification(implSlot); + } + else if (implSlot == unificationGroup.DefiningMethod && implSlot.RequiresSlotUnification()) + { + unificationGroup.AddMethodRequiringSlotUnification(declSlot); + unificationGroup.AddMethodRequiringSlotUnification(implSlot); + } + } + else if (unificationGroup.RequiresSlotUnification(declSlot)) { - if (separatedMethods == null || !separatedMethods.Contains(addDeclGroupMemberMethod)) + if (implSlot.Signature.Equals(unificationGroup.DefiningMethod.Signature, true)) { - unificationGroup.AddToGroup(addDeclGroupMemberMethod); + unificationGroup.AddMethodRequiringSlotUnification(implSlot); + unificationGroup.SetDefiningMethod(implSlot); } } } diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.ToString.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.ToString.cs index 984faa2433e205..e9c394dced421b 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.ToString.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.ToString.cs @@ -46,7 +46,9 @@ public override string ToString() { var sb = new StringBuilder(); - // (Skipping return type to keep things short) + sb.Append(Signature.ReturnType); + sb.Append(" "); + sb.Append(OwningType); sb.Append('.'); sb.Append(DiagnosticName); diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs index 3e204f8fa7546e..3c21f3b2ea8793 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs @@ -114,7 +114,7 @@ public int Length } } - public bool Equals(MethodSignature otherSignature) + public bool Equals(MethodSignature otherSignature, bool allowCovariantReturn = false) { // TODO: Generics, etc. if (this._flags != otherSignature._flags) @@ -124,7 +124,18 @@ public bool Equals(MethodSignature otherSignature) return false; if (this._returnType != otherSignature._returnType) - return false; + { + if (!allowCovariantReturn) + return false; + + // Casting a struct to an interface it implements is allowed, but these two types are not compatible and + // can't be considered a valid covariant return type + if (this._returnType.IsValueType && !otherSignature._returnType.IsValueType) + return false; + + if (!this._returnType.CanCastTo(otherSignature._returnType)) + return false; + } if (this._parameters.Length != otherSignature._parameters.Length) return false; diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs index e76f5e3087057e..e15a2efe10d2a1 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs @@ -411,5 +411,29 @@ public static bool ContainsSignatureVariables(this TypeDesc thisType) return false; } } + + /// + /// Check if MethodImpl requires slot unification. + /// + /// Method to check + /// True when the method is a MethodImpl marked with the RequireMethodImplToRemainInEffect custom attribute, false otherwise. + public static bool RequiresSlotUnification(this MethodDesc method) + { + if (!method.HasCustomAttribute("System.Runtime.CompilerServices", "RequireMethodImplToRemainInEffectAttribute")) + return false; + + MetadataType mdType = method.OwningType as MetadataType; + if (mdType != null) + { + foreach (MethodImplRecord methodImplRecord in mdType.VirtualMethodImplsForType) + { + // Method is a MethodImpl body record with the attribute + if (method == methodImplRecord.Body) + return true; + } + } + + return false; + } } } From f97b9defd8bb297bba12806a3a24fb07f612db8b Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Tue, 5 May 2020 11:57:49 -0700 Subject: [PATCH 13/21] some CR feedback --- .../Common/MetadataVirtualMethodAlgorithm.cs | 44 ++++++++++--------- .../TypeSystem/Common/MethodDesc.ToString.cs | 4 +- .../Common/TypeSystem/Common/MethodDesc.cs | 17 ++++--- .../TypeSystem/Common/TypeSystemHelpers.cs | 28 +++++++----- 4 files changed, 53 insertions(+), 40 deletions(-) diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs index 7f188a89b43a04..f5b1544369b7d1 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; namespace Internal.TypeSystem { @@ -89,6 +90,21 @@ public MethodDesc Current } } + public struct Enumerable + { + private readonly MethodDesc[] _arrayToEnumerate; + + public Enumerable(MethodDesc[] arrayToEnumerate) + { + _arrayToEnumerate = arrayToEnumerate; + } + + public Enumerator GetEnumerator() + { + return new Enumerator(_arrayToEnumerate); + } + } + public UnificationGroup(MethodDesc definingMethod) { DefiningMethod = definingMethod; @@ -97,23 +113,9 @@ public UnificationGroup(MethodDesc definingMethod) public MethodDesc DefiningMethod; - public Enumerator GetEnumerator() - { - return new Enumerator(_members); - } + public Enumerable Members => new Enumerable(_members); - public IEnumerable MethodsRequiringSlotUnification - { - get - { - foreach (var method in _methodsRequiringSlotUnification) - { - if (method == null) - yield break; - yield return method; - } - } - } + public Enumerable MethodsRequiringSlotUnification => new Enumerable(_methodsRequiringSlotUnification); public void AddMethodRequiringSlotUnification(MethodDesc method) { @@ -460,7 +462,7 @@ private static void FindBaseUnificationGroup(MetadataType currentType, Unificati // Start with removing methods that seperated themselves from the group via name/sig matches MethodDescHashtable separatedMethods = null; - foreach (MethodDesc memberMethod in unificationGroup) + foreach (MethodDesc memberMethod in unificationGroup.Members) { MethodDesc nameSigMatchMemberMethod = FindMatchingVirtualMethodOnTypeByNameAndSigWithSlotCheck(memberMethod, currentType, reverseMethodSearch: true); if (nameSigMatchMemberMethod != null && nameSigMatchMemberMethod != memberMethod) @@ -495,7 +497,7 @@ private static void FindBaseUnificationGroup(MetadataType currentType, Unificati if (unificationGroup.RequiresSlotUnification(declSlot) || implSlot.RequiresSlotUnification()) { - if (implSlot.Signature.Equals(unificationGroup.DefiningMethod.Signature, true)) + if (implSlot.Signature.EqualsWithCovariantReturnType(unificationGroup.DefiningMethod.Signature)) { unificationGroup.AddMethodRequiringSlotUnification(declSlot); unificationGroup.AddMethodRequiringSlotUnification(implSlot); @@ -516,7 +518,7 @@ private static void FindBaseUnificationGroup(MetadataType currentType, Unificati FindBaseUnificationGroup(baseType, addDeclGroup); Debug.Assert( addDeclGroup.IsInGroupOrIsDefiningSlot(declSlot) || - (addDeclGroup.RequiresSlotUnification(declSlot) && addDeclGroup.DefiningMethod.Signature.Equals(declSlot.Signature, true))); + (addDeclGroup.RequiresSlotUnification(declSlot) && addDeclGroup.DefiningMethod.Signature.EqualsWithCovariantReturnType(declSlot.Signature))); foreach(MethodDesc methodImplRequiredToRemainInEffect in addDeclGroup.MethodsRequiringSlotUnification) { @@ -530,7 +532,7 @@ private static void FindBaseUnificationGroup(MetadataType currentType, Unificati unificationGroup.AddToGroup(addDeclGroup.DefiningMethod); } - foreach (MethodDesc addDeclGroupMemberMethod in addDeclGroup) + foreach (MethodDesc addDeclGroupMemberMethod in addDeclGroup.Members) { if (separatedMethods == null || !separatedMethods.Contains(addDeclGroupMemberMethod)) { @@ -550,7 +552,7 @@ private static void FindBaseUnificationGroup(MetadataType currentType, Unificati } else if (unificationGroup.RequiresSlotUnification(declSlot)) { - if (implSlot.Signature.Equals(unificationGroup.DefiningMethod.Signature, true)) + if (implSlot.Signature.EqualsWithCovariantReturnType(unificationGroup.DefiningMethod.Signature)) { unificationGroup.AddMethodRequiringSlotUnification(implSlot); unificationGroup.SetDefiningMethod(implSlot); diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.ToString.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.ToString.cs index e9c394dced421b..984faa2433e205 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.ToString.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.ToString.cs @@ -46,9 +46,7 @@ public override string ToString() { var sb = new StringBuilder(); - sb.Append(Signature.ReturnType); - sb.Append(" "); - + // (Skipping return type to keep things short) sb.Append(OwningType); sb.Append('.'); sb.Append(DiagnosticName); diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs index 3c21f3b2ea8793..7482f328ecf064 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs @@ -114,7 +114,17 @@ public int Length } } - public bool Equals(MethodSignature otherSignature, bool allowCovariantReturn = false) + public bool Equals(MethodSignature otherSignature) + { + return Equals(otherSignature, allowCovariantReturn: false); + } + + public bool EqualsWithCovariantReturnType(MethodSignature otherSignature) + { + return Equals(otherSignature, allowCovariantReturn: true); + } + + private bool Equals(MethodSignature otherSignature, bool allowCovariantReturn) { // TODO: Generics, etc. if (this._flags != otherSignature._flags) @@ -128,11 +138,6 @@ public bool Equals(MethodSignature otherSignature, bool allowCovariantReturn = f if (!allowCovariantReturn) return false; - // Casting a struct to an interface it implements is allowed, but these two types are not compatible and - // can't be considered a valid covariant return type - if (this._returnType.IsValueType && !otherSignature._returnType.IsValueType) - return false; - if (!this._returnType.CanCastTo(otherSignature._returnType)) return false; } diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs index e15a2efe10d2a1..acc8f2b618cc7e 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs @@ -416,21 +416,29 @@ public static bool ContainsSignatureVariables(this TypeDesc thisType) /// Check if MethodImpl requires slot unification. /// /// Method to check - /// True when the method is a MethodImpl marked with the RequireMethodImplToRemainInEffect custom attribute, false otherwise. + /// True when the method is marked with the RequireMethodImplToRemainInEffect custom attribute, false otherwise. public static bool RequiresSlotUnification(this MethodDesc method) { - if (!method.HasCustomAttribute("System.Runtime.CompilerServices", "RequireMethodImplToRemainInEffectAttribute")) - return false; - - MetadataType mdType = method.OwningType as MetadataType; - if (mdType != null) + if (method.HasCustomAttribute("System.Runtime.CompilerServices", "RequireMethodImplToRemainInEffectAttribute")) { - foreach (MethodImplRecord methodImplRecord in mdType.VirtualMethodImplsForType) +#if DEBUG + // We shouldn't be calling this for non-MethodImpls, so verify that the method being checked is really a MethodImpl + MetadataType mdType = method.OwningType as MetadataType; + if (mdType != null) { - // Method is a MethodImpl body record with the attribute - if (method == methodImplRecord.Body) - return true; + bool isMethodImpl = false; + foreach (MethodImplRecord methodImplRecord in mdType.VirtualMethodImplsForType) + { + if (method == methodImplRecord.Body) + { + isMethodImpl = true; + break; + } + } + Debug.Assert(isMethodImpl); } +#endif + return true; } return false; From 1329feadbcf6916b07fc3800475795ce03320f0d Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Thu, 7 May 2020 15:54:08 -0700 Subject: [PATCH 14/21] Add unit test coverage for delegates --- .../UnitTest/UnitTestDelegates.il | 1177 +++++++++++++++++ .../UnitTest/UnitTestDelegates.ilproj | 10 + 2 files changed, 1187 insertions(+) create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il new file mode 100644 index 00000000000000..1fec32baeb3628 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il @@ -0,0 +1,1177 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +.assembly extern System.Runtime { } +.assembly UnitTestDelegates { } + + +// ======================================================================================== +// 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 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 private auto ansi sealed En extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname int32 value__ +} + + +// ======================================================================================== +// Main base type with various virtual methods that will be overriden 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 + } + + .method public hidebysig newslot virtual instance int32[] RetIntArr() + { + ldstr "base.retintarr" + call void [System.Console]System.Console::WriteLine(string) + 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 NonGenThroughGen2 NonGenThroughGenFunc(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .override method instance class B class GenBaseType::NonGenThroughGenFunc(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.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .override method instance class B class GenBaseType::GenToNonGen(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.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .override method instance class GenRetType class GenBaseType::MyGenFunc(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.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .override method instance class GenRetType> class GenBaseType::MyGenFunc(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 specialname rtspecialname instance void .ctor() cil managed { ret } + + .method public hidebysig newslot virtual instance class NonGenThroughGen4 NonGenThroughGenFunc(string& res) + { + .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) + ldarg.1 + ldstr "NonGenThroughGen4 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(string& res) + ldarg.1 + ldstr "GenToNonGen3 TestType.GenToNonGen()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class NonGenericDerived4 MyGenFunc(string& res) + { + .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "NonGenericDerived4 TestType.MyGenFunc()" + stind.ref + ldnull + ret + } + + .method public hidebysig newslot virtual instance class GenDerive3 MyGenFunc(string& res) + { + .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) + ldarg.1 + ldstr "GenDerive3 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.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .override method instance object class GenBaseType::MyFunc(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.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .override method instance class B class GenBaseType::MyFunc(string& res) + ldarg.1 + ldstr "C TestType.MyFunc()" + 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 B 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 B 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 GenRetType 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 GenRetType> 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 B MyFunc(string& res) + { + ldstr "Should never execute this method" + newobj instance void [System.Runtime]System.Exception::.ctor(string) + throw + } +} + + +// ======================================================================================== +// Delegates that will be used for the various method calls +// ======================================================================================== + +.class private auto ansi sealed Del_Obj extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_Obj::.ctor + + .method public hidebysig newslot virtual + instance object Invoke(string& res) runtime managed + { + } // end of method Del_Obj::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_Obj::BeginInvoke + + .method public hidebysig newslot virtual + instance object EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_Obj::EndInvoke + +} // end of class Del_Obj + +.class private auto ansi sealed Del_B extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_B::.ctor + + .method public hidebysig newslot virtual + instance class B Invoke(string& res) runtime managed + { + } // end of method Del_B::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_B::BeginInvoke + + .method public hidebysig newslot virtual + instance class B EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_B::EndInvoke + +} // end of class Del_B + +.class private auto ansi sealed Del_GenRetType_int_object extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_GenRetType_int_object::.ctor + + .method public hidebysig newslot virtual + instance class GenRetType + Invoke(string& res) runtime managed + { + } // end of method Del_GenRetType_int_object::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_GenRetType_int_object::BeginInvoke + + .method public hidebysig newslot virtual + instance class GenRetType + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_GenRetType_int_object::EndInvoke + +} // end of class Del_GenRetType_int_object + +.class private auto ansi sealed Del_GenRetType extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_GenRetType::.ctor + + .method public hidebysig newslot virtual + instance class GenRetType> + Invoke(string& res) runtime managed + { + } // end of method Del_GenRetType::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_GenRetType::BeginInvoke + + .method public hidebysig newslot virtual + instance class GenRetType> + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_GenRetType::EndInvoke + +} // end of class Del_GenRetType + +.class private auto ansi sealed Del_NonGenThroughGen2 extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_NonGenThroughGen2::.ctor + + .method public hidebysig newslot virtual + instance class NonGenThroughGen2 + Invoke(string& res) runtime managed + { + } // end of method Del_NonGenThroughGen2::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_NonGenThroughGen2::BeginInvoke + + .method public hidebysig newslot virtual + instance class NonGenThroughGen2 + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_NonGenThroughGen2::EndInvoke + +} // end of class Del_NonGenThroughGen2 + +.class private auto ansi sealed Del_GenToNonGen1 extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_GenToNonGen1::.ctor + + .method public hidebysig newslot virtual + instance class GenToNonGen1> + Invoke(string& res) runtime managed + { + } // end of method Del_GenToNonGen1::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_GenToNonGen1::BeginInvoke + + .method public hidebysig newslot virtual + instance class GenToNonGen1> + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_GenToNonGen1::EndInvoke + +} // end of class Del_GenToNonGen1 + +.class private auto ansi sealed Del_NonGenericDerived1 extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_NonGenericDerived1::.ctor + + .method public hidebysig newslot virtual + instance class NonGenericDerived1 + Invoke(string& res) runtime managed + { + } // end of method Del_NonGenericDerived1::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_NonGenericDerived1::BeginInvoke + + .method public hidebysig newslot virtual + instance class NonGenericDerived1 + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_NonGenericDerived1::EndInvoke + +} // end of class Del_NonGenericDerived1 + +.class private auto ansi sealed Del_GenDerive1 extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_GenDerive1::.ctor + + .method public hidebysig newslot virtual + instance class GenDerive1> + Invoke(string& res) runtime managed + { + } // end of method Del_GenDerive1::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_GenDerive1::BeginInvoke + + .method public hidebysig newslot virtual + instance class GenDerive1> + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_GenDerive1::EndInvoke + +} // end of class Del_GenDerive1 + +.class private auto ansi sealed Del_NonGenThroughGen4 extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_NonGenThroughGen4::.ctor + + .method public hidebysig newslot virtual + instance class NonGenThroughGen4 + Invoke(string& res) runtime managed + { + } // end of method Del_NonGenThroughGen4::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_NonGenThroughGen4::BeginInvoke + + .method public hidebysig newslot virtual + instance class NonGenThroughGen4 + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_NonGenThroughGen4::EndInvoke + +} // end of class Del_NonGenThroughGen4 + +.class private auto ansi sealed Del_GenToNonGen3 extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_GenToNonGen3::.ctor + + .method public hidebysig newslot virtual + instance class GenToNonGen3 + Invoke(string& res) runtime managed + { + } // end of method Del_GenToNonGen3::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_GenToNonGen3::BeginInvoke + + .method public hidebysig newslot virtual + instance class GenToNonGen3 + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_GenToNonGen3::EndInvoke + +} // end of class Del_GenToNonGen3 + +.class private auto ansi sealed Del_NonGenericDerived4 extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_NonGenericDerived4::.ctor + + .method public hidebysig newslot virtual + instance class NonGenericDerived4 + Invoke(string& res) runtime managed + { + } // end of method Del_NonGenericDerived4::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_NonGenericDerived4::BeginInvoke + + .method public hidebysig newslot virtual + instance class NonGenericDerived4 + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_NonGenericDerived4::EndInvoke + +} // end of class Del_NonGenericDerived4 + +.class private auto ansi sealed Del_GenDerive3 extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_GenDerive3::.ctor + + .method public hidebysig newslot virtual + instance class GenDerive3 + Invoke(string& res) runtime managed + { + } // end of method Del_GenDerive3::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_GenDerive3::BeginInvoke + + .method public hidebysig newslot virtual + instance class GenDerive3 + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_GenDerive3::EndInvoke + +} // end of class Del_GenDerive3 + +.class private auto ansi sealed Del_GenRetType_U_V extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_GenRetType_U_V::.ctor + + .method public hidebysig newslot virtual + instance class GenRetType + Invoke(string& res) runtime managed + { + } // end of method Del_GenRetType_U_V::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_GenRetType_U_V::BeginInvoke + + .method public hidebysig newslot virtual + instance class GenRetType + EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_GenRetType_U_V::EndInvoke + +} // end of class Del_GenRetType_U_V + +.class private auto ansi sealed Del_C extends [System.Runtime]System.MulticastDelegate +{ + .method public hidebysig specialname rtspecialname + instance void .ctor(object 'object', + native int 'method') runtime managed + { + } // end of method Del_C::.ctor + + .method public hidebysig newslot virtual + instance class C Invoke(string& res) runtime managed + { + } // end of method Del_C::Invoke + + .method public hidebysig newslot virtual + instance class [System.Runtime]System.IAsyncResult + BeginInvoke(string& res, + class [System.Runtime]System.AsyncCallback callback, + object 'object') runtime managed + { + } // end of method Del_C::BeginInvoke + + .method public hidebysig newslot virtual + instance class C EndInvoke(string& res, + class [System.Runtime]System.IAsyncResult result) runtime managed + { + } // end of method Del_C::EndInvoke + +} // end of class Del_C + + + +// ======================================================================================== + +.class private auto ansi beforefieldinit CMain extends [System.Runtime]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 + // Code size 164 (0xa4) + .maxstack 2 + .locals init (bool V_0) + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: call bool [System.Runtime]System.String::op_Equality(string, + string) + IL_0007: stloc.0 + IL_0008: ldstr "EXPECTED: " + IL_000d: ldarg.0 + IL_000e: call string [System.Runtime]System.String::Concat(string, + string) + IL_0013: call void [System.Console]System.Console::WriteLine(string) + IL_0018: ldstr "ACTUAL1 : " + IL_001d: ldarg.1 + IL_001e: call string [System.Runtime]System.String::Concat(string, + string) + IL_0023: call void [System.Console]System.Console::WriteLine(string) + IL_0028: ldarg.2 + IL_0029: call bool [System.Runtime]System.String::IsNullOrEmpty(string) + IL_002e: brtrue.s IL_004e + + IL_0030: ldstr "ACTUAL2 : " + IL_0035: ldarg.2 + IL_0036: call string [System.Runtime]System.String::Concat(string, + string) + IL_003b: call void [System.Console]System.Console::WriteLine(string) + 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) + 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) + IL_0054: brtrue.s IL_0074 + + IL_0056: ldstr "ACTUAL3 : " + IL_005b: ldarg.3 + IL_005c: call string [System.Runtime]System.String::Concat(string, + string) + IL_0061: call void [System.Console]System.Console::WriteLine(string) + 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) + 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) + IL_007b: brtrue.s IL_009d + + IL_007d: ldstr "ACTUAL4 : " + IL_0082: ldarg.s d + IL_0084: call string [System.Runtime]System.String::Concat(string, + string) + IL_0089: call void [System.Console]System.Console::WriteLine(string) + 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) + IL_0099: br.s IL_009c + + IL_009b: ldc.i4.0 + IL_009c: stloc.0 + IL_009d: call void [System.Console]System.Console::WriteLine() + IL_00a2: ldloc.0 + IL_00a3: ret + } // end of method Program::CheckResults + + + // ============== Test using GenTestType ============== // + // These test methods will callvirt each method using: + // 1) The signature from GetBaseType + // 2) The signature from GenMiddleType with covariant returns (when applicable) + // 3) The signature from GenTestType with covariant returns + // And verify that the override on GetTestType is the one that executes + + .method public hidebysig static bool RunTest1() cil managed noinlining + { + .locals init (string res1, string res2, string res3, class GenTestType thisPtr) + + newobj instance void class GenTestType::.ctor() + stloc.s thisPtr + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance object class GenBaseType::MyFunc(string&) + newobj instance void Del_Obj::.ctor(object, native int) + ldloca.s 0 + callvirt instance object Del_Obj::Invoke(string&) + pop + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class GenRetType class GenTestType::MyFunc(string&) + newobj instance void class Del_GenRetType_U_V::.ctor(object, native int) + ldloca.s 1 + callvirt instance class GenRetType class Del_GenRetType_U_V::Invoke(string&) + pop + + ldstr "GenRetType TestType.MyFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public hidebysig static bool RunTest2() cil managed noinlining + { + .locals init (string res1, string res2, string res3, class GenTestType thisPtr) + + newobj instance void class GenTestType::.ctor() + stloc.s thisPtr + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class B class GenBaseType::MyFunc(string&) + newobj instance void Del_B::.ctor(object, native int) + ldloca.s 0 + callvirt instance class B Del_B::Invoke(string&) + pop + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class C class GenTestType::MyFunc(string&) + newobj instance void Del_C::.ctor(object, native int) + ldloca.s 1 + callvirt instance class C Del_C::Invoke(string&) + pop + + ldstr "C TestType.MyFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public hidebysig static bool RunTest3() cil managed noinlining + { + .locals init (string res1, string res2, string res3, class GenTestType thisPtr) + + newobj instance void class GenTestType::.ctor() + stloc.s thisPtr + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class GenRetType> class GenBaseType::MyGenFunc(string&) + newobj instance void class Del_GenRetType::.ctor(object, native int) + ldloca.s 0 + callvirt instance class GenRetType> class Del_GenRetType::Invoke(string&) + pop + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class GenDerive1> class GenMiddleType::MyGenFunc(string&) + newobj instance void class Del_GenDerive1::.ctor(object, native int) + ldloca.s 1 + callvirt instance class GenDerive1> class Del_GenDerive1::Invoke(string&) + pop + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class GenDerive3 class GenTestType::MyGenFunc(string&) + newobj instance void class Del_GenDerive3::.ctor(object, native int) + ldloca.s 2 + callvirt instance class GenDerive3 class Del_GenDerive3::Invoke(string&) + pop + + ldstr "GenDerive3 TestType.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public hidebysig static bool RunTest4() cil managed noinlining + { + .locals init (string res1, string res2, string res3, class GenTestType thisPtr) + + newobj instance void class GenTestType::.ctor() + stloc.s thisPtr + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class GenRetType class GenBaseType::MyGenFunc(string&) + newobj instance void class Del_GenRetType_int_object::.ctor(object, native int) + ldloca.s 0 + callvirt instance class GenRetType class Del_GenRetType_int_object::Invoke(string&) + pop + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class NonGenericDerived1 class GenMiddleType::MyGenFunc(string&) + newobj instance void class Del_NonGenericDerived1::.ctor(object, native int) + ldloca.s 1 + callvirt instance class NonGenericDerived1 class Del_NonGenericDerived1::Invoke(string&) + pop + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class NonGenericDerived4 class GenTestType::MyGenFunc(string&) + newobj instance void class Del_NonGenericDerived4::.ctor(object, native int) + ldloca.s 2 + callvirt instance class NonGenericDerived4 class Del_NonGenericDerived4::Invoke(string&) + pop + + ldstr "NonGenericDerived4 TestType.MyGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public hidebysig static bool RunTest5() cil managed noinlining + { + .locals init (string res1, string res2, string res3, class GenTestType thisPtr) + + newobj instance void class GenTestType::.ctor() + stloc.s thisPtr + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class B class GenBaseType::GenToNonGen(string&) + newobj instance void class Del_B::.ctor(object, native int) + ldloca.s 0 + callvirt instance class B class Del_B::Invoke(string&) + pop + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class GenToNonGen1> class GenMiddleType::GenToNonGen(string&) + newobj instance void class Del_GenToNonGen1::.ctor(object, native int) + ldloca.s 1 + callvirt instance class GenToNonGen1> class Del_GenToNonGen1::Invoke(string&) + pop + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class GenToNonGen3 class GenTestType::GenToNonGen(string&) + newobj instance void class Del_GenToNonGen3::.ctor(object, native int) + ldloca.s 2 + callvirt instance class GenToNonGen3 class Del_GenToNonGen3::Invoke(string&) + pop + + ldstr "GenToNonGen3 TestType.GenToNonGen()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public hidebysig static bool RunTest6() cil managed noinlining + { + .locals init (string res1, string res2, string res3, class GenTestType thisPtr) + + newobj instance void class GenTestType::.ctor() + stloc.s thisPtr + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class B class GenBaseType::NonGenThroughGenFunc(string&) + newobj instance void class Del_B::.ctor(object, native int) + ldloca.s 0 + callvirt instance class B class Del_B::Invoke(string&) + pop + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class NonGenThroughGen2 class GenMiddleType::NonGenThroughGenFunc(string&) + newobj instance void class Del_NonGenThroughGen2::.ctor(object, native int) + ldloca.s 1 + callvirt instance class NonGenThroughGen2 class Del_NonGenThroughGen2::Invoke(string&) + pop + + ldloc.s thisPtr + ldloc.s thisPtr + ldvirtftn instance class NonGenThroughGen4 class GenTestType::NonGenThroughGenFunc(string&) + newobj instance void class Del_NonGenThroughGen4::.ctor(object, native int) + ldloca.s 2 + callvirt instance class NonGenThroughGen4 class Del_NonGenThroughGen4::Invoke(string&) + pop + + ldstr "NonGenThroughGen4 TestType.NonGenThroughGenFunc()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method private hidebysig static int32 Main(string[] args) cil managed + { + .entrypoint + .maxstack 2 + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + T1: + call bool CMain::RunTest1() + brtrue.s T2 + ldc.i4.0 + stloc.0 + + T2: + call bool CMain::RunTest2() + brtrue.s T3 + ldc.i4.0 + stloc.0 + + T3: + call bool CMain::RunTest3() + brtrue.s T4 + ldc.i4.0 + stloc.0 + + T4: + call bool CMain::RunTest4() + brtrue.s T5 + ldc.i4.0 + stloc.0 + + T5: + call bool CMain::RunTest5() + brtrue.s T6 + ldc.i4.0 + stloc.0 + + T6: + call bool CMain::RunTest6() + brtrue.s DONE + ldc.i4.0 + 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 [System.Runtime]System.Object::.ctor() + ret + } +} diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj new file mode 100644 index 00000000000000..1667d3b14ac0ba --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + From 997074f6becdfefbd248d43b0d2e284f370cc29e Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 15 May 2020 00:07:05 +0200 Subject: [PATCH 15/21] Fix handling of covariant and contravariant generic interfaces Also add tests for those. --- src/coreclr/src/vm/class.cpp | 4 +- src/coreclr/src/vm/typehandle.cpp | 4 +- .../CovariantReturns/Interfaces/UnitTest.il | 120 +++++++++++++++++- 3 files changed, 122 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index 3cf54297fd806c..1964695184e462 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -1025,6 +1025,7 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) // Validation not applicable to interface types and value types, since these are not currently // supported with the covariant return feature + if (pMT->IsInterface() || pMT->IsValueType()) return; @@ -1069,8 +1070,7 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) // Structs can be casted to the interfaces they implement, but they are not compatible according to ECMA I.8.7.1 bool isCastFromValueTypeToReferenceType = hType2.IsValueType() && !hType1.IsValueType(); - TypeHandlePairList visited(hType1, hType2, NULL); - if (isCastFromValueTypeToReferenceType || !hType2.GetMethodTable()->CanCastTo(hType1.GetMethodTable(), &visited)) + if (isCastFromValueTypeToReferenceType || !hType2.GetMethodTable()->CanCastTo(hType1.GetMethodTable(), NULL)) { SString strAssemblyName; pMD->GetAssembly()->GetDisplayName(strAssemblyName); diff --git a/src/coreclr/src/vm/typehandle.cpp b/src/coreclr/src/vm/typehandle.cpp index d9b1a9c2466177..2e19a3e5428e83 100644 --- a/src/coreclr/src/vm/typehandle.cpp +++ b/src/coreclr/src/vm/typehandle.cpp @@ -575,7 +575,7 @@ BOOL TypeHandle::IsBoxedAndCanCastTo(TypeHandle type, TypeHandlePairList *pPairL GC_TRIGGERS; INJECT_FAULT(COMPlusThrowOM()); - LOADS_TYPE(CLASS_DEPENDENCIES_LOADED); + LOADS_TYPE(CLASS_LOAD_EXACTPARENTS); // The caller should check for an exact match. // That will cover the cast of a (unboxed) valuetype to itself. @@ -622,7 +622,7 @@ BOOL TypeHandle::CanCastTo(TypeHandle type, TypeHandlePairList *pVisited) const MODE_ANY; INJECT_FAULT(COMPlusThrowOM()); - LOADS_TYPE(CLASS_DEPENDENCIES_LOADED); + LOADS_TYPE(CLASS_LOAD_EXACTPARENTS); } CONTRACTL_END diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il index 7b0d94d11c5f5b..144f8c1c2156dc 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il @@ -21,6 +21,13 @@ .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 { } @@ -71,6 +78,22 @@ 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 @@ -230,7 +253,29 @@ ldnull ret } - + + .method public hidebysig newslot virtual instance class ICovariant MyFuncCovariant(string& res) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.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.RequireMethodImplToRemainInEffectAttribute::.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 // ======================================================================================== @@ -275,6 +320,20 @@ 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 + } } // ======================================================================================== @@ -646,6 +705,51 @@ ret } + .method public static bool RunTest7() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class ICovariant class GenBaseType::MyFuncCovariant(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class ICovariant class GenTestType::MyFuncCovariant(string&) + pop + + ldstr "ICovariant TestType.MyFuncCovariant()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } + + .method public static bool RunTest8() noinlining + { + .locals init (string res1, string res2, string res3) + + newobj instance void class GenTestType::.ctor() + ldloca.s 0 + callvirt instance class IContravariant class GenBaseType::MyFuncContravariant(string&) + pop + + newobj instance void class GenTestType::.ctor() + ldloca.s 1 + callvirt instance class IContravariant class GenTestType::MyFuncContravariant(string&) + pop + + ldstr "IContravariant TestType.MyFuncContravariant()" + ldloc.0 + ldloc.1 + ldloc.2 + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + ret + } // ============== Test using GenMiddleType ============== // // These test methods will callvirt each method using: @@ -1001,10 +1105,22 @@ T6: call bool CMain::RunTest6() + brtrue.s T7 + ldc.i4.0 + stloc.0 + + T7: + call bool CMain::RunTest7() + brtrue.s T8 + ldc.i4.0 + stloc.0 + + T8: + call bool CMain::RunTest8() brtrue.s M1 ldc.i4.0 stloc.0 - + // ===================================================================================== // M1: From ed9fb4c50fa3012df94045d8cd9d20ed0cf2accd Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Mon, 18 May 2020 23:36:18 +0200 Subject: [PATCH 16/21] Added test cases to interfaces unit test Based on PR feedback, I've added test cases to verify the load level asserts change. --- .../CovariantReturns/Interfaces/UnitTest.il | 98 ++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il index 144f8c1c2156dc..d93298c6ae699a 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il @@ -54,6 +54,18 @@ .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 overriden later // ======================================================================================== @@ -126,6 +138,15 @@ ldnull ret } + + .method public hidebysig newslot virtual instance class IVariant> MultiLevelGenericVariantFunc(string&) + { + ldarg.1 + ldstr "IVariant> GenBaseType.MultiLevelGenericVariantFunc()" + stind.ref + ldnull + ret + } } // ======================================================================================== @@ -404,6 +425,17 @@ ldnull ret } + + .method public hidebysig newslot virtual instance class IVariant MultiLevelGenericVariantFunc(string&) + { + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.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 + } } @@ -442,6 +474,19 @@ } } +.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.RequireMethodImplToRemainInEffectAttribute::.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 @@ -751,6 +796,26 @@ ret } + .method public static bool RunTest9() noinlining + { + .locals init (string res1) + newobj instance void class GenMoreDerived::.ctor() + ldloca.s 0 + callvirt instance class IVariant class GenMoreDerived::MultiLevelGenericVariantFunc(string&) + pop + + ldstr "class IVariant GenMoreDerived.MultiLevelGenericVariantFunc()" + ldloc.0 + ldnull + ldnull + ldnull + call bool CMain::CheckResults(string,string,string,string,string) + + ret + } + + + // ============== Test using GenMiddleType ============== // // These test methods will callvirt each method using: // 1) The signature from GetBaseType @@ -1062,6 +1127,13 @@ 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( string[] args) cil managed @@ -1117,6 +1189,12 @@ T8: call bool CMain::RunTest8() + brtrue.s T9 + ldc.i4.0 + stloc.0 + + T9: + call bool CMain::RunTest9() brtrue.s M1 ldc.i4.0 stloc.0 @@ -1213,13 +1291,31 @@ stloc.0 ldstr "FAIL: did not catch expected TypeLoadException when loading Invalid2." call void [System.Console]System.Console::WriteLine(string) - leave.s DONE + 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 } From 6eaaa1a6dfe3b2816363254d0b165390420ac2f2 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Wed, 20 May 2020 23:07:21 +0200 Subject: [PATCH 17/21] Fix Nullable handling and add more tests The attempt to overload method with int32 return value by a method with Nullable was asserting in CanCastTo. This change fixes it by pre-checking this case before calling into CanCastTo. I've also slightly refactored the ValidateMethodsWithCovariantReturnTypes by extracting the compatible-with stuff into IsCompatibleWith method. Added tests to test various compatible-with differences from the originally used CanCastTo --- src/coreclr/src/vm/class.cpp | 28 +- src/coreclr/src/vm/clsload.hpp | 2 + .../UnitTest/CompatibleWithTest.il | 442 ++++++++++++++++++ .../UnitTest/CompatibleWithTest.ilproj | 10 + 4 files changed, 478 insertions(+), 4 deletions(-) create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il create mode 100644 src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.ilproj diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index 1964695184e462..46514a5ed95080 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -975,6 +975,29 @@ void ClassLoader::LoadExactParents(MethodTable *pMT) RETURN; } +// Checks if two types are compatible according to compatible-with as described in ECMA 335 I.8.7.1 +// Most of the checks are performed by the CanCastTo, but with some cases pre-filtered out. +// +/*static*/ +bool ClassLoader::IsCompatibleWith(TypeHandle hType1, TypeHandle hType2) +{ + // Structs can be casted to the interfaces they implement, but they are not compatible according to ECMA I.8.7.1 + bool isCastFromValueTypeToReferenceType = hType2.IsValueType() && !hType1.IsValueType(); + if (isCastFromValueTypeToReferenceType) + { + return false; + } + + // Nullable can be casted to T, but this is not compatible according to ECMA I.8.7.1 + bool isCastFromNullableOfTtoT = hType1.GetMethodTable()->IsNullable() && hType2.IsEquivalentTo(hType1.GetMethodTable()->GetInstantiation()[0]); + if (isCastFromNullableOfTtoT) + { + return false; + } + + return hType2.GetMethodTable()->CanCastTo(hType1.GetMethodTable(), NULL); +} + /*static*/ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) { @@ -1067,10 +1090,7 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) { GCX_COOP(); - // Structs can be casted to the interfaces they implement, but they are not compatible according to ECMA I.8.7.1 - bool isCastFromValueTypeToReferenceType = hType2.IsValueType() && !hType1.IsValueType(); - - if (isCastFromValueTypeToReferenceType || !hType2.GetMethodTable()->CanCastTo(hType1.GetMethodTable(), NULL)) + if (!IsCompatibleWith(hType1, hType2)) { SString strAssemblyName; pMD->GetAssembly()->GetDisplayName(strAssemblyName); diff --git a/src/coreclr/src/vm/clsload.hpp b/src/coreclr/src/vm/clsload.hpp index c082982c886674..042c45c513e210 100644 --- a/src/coreclr/src/vm/clsload.hpp +++ b/src/coreclr/src/vm/clsload.hpp @@ -975,6 +975,8 @@ class ClassLoader static void ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT); + static bool IsCompatibleWith(TypeHandle hType1, TypeHandle hType2); + // Create a non-canonical instantiation of a generic type based off the canonical instantiation // (For example, MethodTable for List is based on the MethodTable for List<__Canon>) static TypeHandle CreateTypeHandleForNonCanonicalGenericInstantiation(TypeKey *pTypeKey, diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il new file mode 100644 index 00000000000000..2f809a4376d3db --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il @@ -0,0 +1,442 @@ +.assembly extern System.Console { } +.assembly extern System.Collections { } +.assembly extern System.Runtime { } +.assembly extern mscorlib { } +.assembly UnitTest { } + +.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() + { + ret + } + + .method public hidebysig newslot virtual instance class [System.Runtime]System.Collections.Generic.IList`1 M2() + { + ret + } + + .method public hidebysig newslot virtual instance int32 M3() + { + ret + } + + .method public hidebysig newslot virtual instance valuetype [mscorlib]System.Nullable`1 M4() + { + ret + } + + .method public hidebysig newslot virtual instance class [System.Runtime]System.Collections.Generic.IList`1 M5() + { + ret + } + + .method public hidebysig newslot virtual instance native int[] M6() + { + 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(); + 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(); + 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(); + 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(); + 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(); + 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(); + 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(); + 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(); + 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(); + ret + } +} + +.class public auto ansi beforefieldinit Main extends [mscorlib]System.Object +{ + .method public static void RunTestC1() noinlining + { + newobj instance void class C1::.ctor() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC2() noinlining + { + newobj instance void class C2::.ctor() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC3() noinlining + { + newobj instance void class C3::.ctor() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC4() noinlining + { + newobj instance void class C4::.ctor() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC5() noinlining + { + newobj instance void class C5::.ctor() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC6() noinlining + { + newobj instance void class C6::.ctor() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC7() noinlining + { + newobj instance void class C7::.ctor() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC8() noinlining + { + newobj instance void class C8::.ctor() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC9() noinlining + { + newobj instance void class C9::.ctor() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public static void RunTestC10() noinlining + { + newobj instance void class C10::.ctor() + pop + ldstr "Succeeded" + call void [System.Console]System.Console::WriteLine(string) + ret + } + + .method public hidebysig static int32 Main(string[] args) cil managed + { + .entrypoint + .locals init ( bool result ) + + ldc.i4.1 + stloc.0 + + ldstr "C1" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC1() + leave.s CC2 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught unexpected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + ldc.i4.0 + stloc.0 + leave.s CC2 + } + +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 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) + + .try + { + call void Main::RunTestC3() + leave.s CC4 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught unexpected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + 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: + ldstr "C6: override int32[] by uint32[]" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC6() + leave.s CC7 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught unexpected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + ldc.i4.0 + stloc.0 + leave.s CC7 + } +CC7: + ldstr "C7: override IList1 by uint32[]" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC7() + leave.s CC8 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught unexpected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + call void [System.Console]System.Console::WriteLine(object) + ldc.i4.0 + stloc.0 + leave.s CC8 + } +CC8: + ldstr "C8: override IList by Derived[]" + call void [System.Console]System.Console::WriteLine(string) + + .try + { + call void Main::RunTestC8() + leave.s CC9 + } + catch [mscorlib]System.TypeLoadException + { + ldstr "Caught unexpected TypeLoadException:" + call void [System.Console]System.Console::WriteLine(string) + 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 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/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.ilproj b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.ilproj new file mode 100644 index 00000000000000..2a6c4198b627a9 --- /dev/null +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.ilproj @@ -0,0 +1,10 @@ + + + Exe + BuildAndRun + 0 + + + + + From 688c2638733839d302676eb6ebb022cb592925a7 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 22 May 2020 19:35:04 +0200 Subject: [PATCH 18/21] Reflect Fadi's feedback - limit the GCX_COOP scope --- src/coreclr/src/vm/class.cpp | 41 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index 46514a5ed95080..1a5a764a33d94d 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -995,7 +995,10 @@ bool ClassLoader::IsCompatibleWith(TypeHandle hType1, TypeHandle hType2) return false; } - return hType2.GetMethodTable()->CanCastTo(hType1.GetMethodTable(), NULL); + { + GCX_COOP(); + return hType2.GetMethodTable()->CanCastTo(hType1.GetMethodTable(), NULL); + } } /*static*/ @@ -1087,31 +1090,27 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) _ASSERTE(hType1.GetMethodTable() != NULL); _ASSERTE(hType2.GetMethodTable() != NULL); + if (!IsCompatibleWith(hType1, hType2)) { - GCX_COOP(); + SString strAssemblyName; + pMD->GetAssembly()->GetDisplayName(strAssemblyName); - if (!IsCompatibleWith(hType1, hType2)) - { - SString strAssemblyName; - pMD->GetAssembly()->GetDisplayName(strAssemblyName); + SString strInvalidTypeName; + TypeString::AppendType(strInvalidTypeName, TypeHandle(pMD->GetMethodTable())); - SString strInvalidTypeName; - TypeString::AppendType(strInvalidTypeName, TypeHandle(pMD->GetMethodTable())); + SString strInvalidMethodName; + TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation()); - SString strInvalidMethodName; - TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation()); + SString strParentMethodName; + TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation()); - SString strParentMethodName; - TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation()); - - COMPlusThrow( - kTypeLoadException, - IDS_CLASSLOAD_MI_BADRETURNTYPE, - strInvalidMethodName, - strInvalidTypeName, - strAssemblyName, - strParentMethodName); - } + COMPlusThrow( + kTypeLoadException, + IDS_CLASSLOAD_MI_BADRETURNTYPE, + strInvalidMethodName, + strInvalidTypeName, + strAssemblyName, + strParentMethodName); } } From 3636d03d82074656be3e3214710f7a1d1b55c57c Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 26 May 2020 20:59:48 +0200 Subject: [PATCH 19/21] Reflect PR feedback - Change the CompatibleWithTest to call virtual methods on test classes instead of just instantiating the classes. - Update crossgen2 similar to the runtime to have IsCompatibleWith method doing the same pre-filtering before calling CanCastTo. --- .../Common/TypeSystem/Common/CastingHelper.cs | 25 +++++++++++++++++ .../Common/TypeSystem/Common/MethodDesc.cs | 2 +- .../UnitTest/CompatibleWithTest.il | 27 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs index d850cc6b334b28..86cf445f2b1047 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs @@ -20,6 +20,31 @@ public static bool CanCastTo(this TypeDesc thisType, TypeDesc otherType) return thisType.CanCastToInternal(otherType, null); } + public static bool IsCompatibleWith(this TypeDesc thisType, TypeDesc otherType) + { + // Structs can be cast to the interfaces they implement, but they are not compatible according to ECMA I.8.7.1 + bool isCastFromValueTypeToReferenceType = otherType.IsValueType && !thisType.IsValueType; + if (isCastFromValueTypeToReferenceType) + { + return false; + } + + // Nullable can be cast to T, but this is not compatible according to ECMA I.8.7.1 + bool isCastFromNullableOfTtoT = thisType.IsNullable && otherType.IsEquivalentTo(thisType.Instantiation[0]); + if (isCastFromNullableOfTtoT) + { + return false; + } + + return otherType.CanCastTo(thisType); + } + + private static bool IsEquivalentTo(this TypeDesc thisType, TypeDesc otherType) + { + // TODO: Once type equivalence is implemented, this implementation needs to be enhanced to honor it. + return thisType.Equals(otherType); + } + private static bool CanCastToInternal(this TypeDesc thisType, TypeDesc otherType, StackOverflowProtect protect) { if (thisType == otherType) diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs index 7482f328ecf064..e9290512641a17 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs @@ -138,7 +138,7 @@ private bool Equals(MethodSignature otherSignature, bool allowCovariantReturn) if (!allowCovariantReturn) return false; - if (!this._returnType.CanCastTo(otherSignature._returnType)) + if (!otherSignature._returnType.IsCompatibleWith(this._returnType)) return false; } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il index 2f809a4376d3db..ae503e14ab11bf 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest.il @@ -13,31 +13,38 @@ .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 } } @@ -49,6 +56,7 @@ .method public hidebysig newslot virtual instance class [System.Runtime]System.Collections.Generic.IList`1 M1() { .override method instance int32[] C1::M1(); + ldnull ret } } @@ -60,6 +68,7 @@ .method public hidebysig newslot virtual instance int32[] M2() { .override method instance class [System.Runtime]System.Collections.Generic.IList`1 C1::M2(); + ldnull ret } } @@ -71,6 +80,8 @@ .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 } } @@ -82,6 +93,7 @@ .method public hidebysig virtual instance int32 M4() { .override method instance valuetype [mscorlib]System.Nullable`1 C1::M4(); + ldc.i4.0 ret } } @@ -93,6 +105,7 @@ .method public hidebysig virtual instance uint32[] M1() { .override method instance int32[] C1::M1(); + ldnull ret } } @@ -104,6 +117,7 @@ .method public hidebysig newslot virtual instance uint32[] M2() { .override method instance class [System.Runtime]System.Collections.Generic.IList`1 C1::M2(); + ldnull ret } } @@ -115,6 +129,7 @@ .method public hidebysig newslot virtual instance class Derived[] M5() { .override method instance class [System.Runtime]System.Collections.Generic.IList`1 C1::M5(); + ldnull ret } } @@ -126,6 +141,7 @@ .method public hidebysig virtual instance uint64[] M6() { .override method instance native int[] C1::M6(); + ldnull ret } } @@ -137,6 +153,7 @@ .method public hidebysig virtual instance uint32[] M6() { .override method instance native int[] C1::M6(); + ldnull ret } } @@ -146,6 +163,7 @@ .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) @@ -155,6 +173,7 @@ .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) @@ -164,6 +183,7 @@ .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) @@ -173,6 +193,7 @@ .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) @@ -182,6 +203,7 @@ .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) @@ -191,6 +213,7 @@ .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) @@ -200,6 +223,7 @@ .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) @@ -209,6 +233,7 @@ .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) @@ -218,6 +243,7 @@ .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) @@ -227,6 +253,7 @@ .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) From c05f07546d916518b4e3214e8d60dc666b38f104 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Mon, 1 Jun 2020 12:21:38 +0200 Subject: [PATCH 20/21] Rename the attribute to PreserveBaseOverridesAttribute --- .../features/covariant-return-methods.md | 8 ++++---- .../TypeSystem/Common/TypeSystemHelpers.cs | 4 ++-- src/coreclr/src/vm/class.cpp | 10 +++++----- src/coreclr/src/vm/wellknownattributes.h | 6 +++--- .../CovariantReturns/Interfaces/UnitTest.il | 20 +++++++++---------- .../UnitTest/AttributeTesting.il | 8 ++++---- .../UnitTest/OverrideMoreDerivedReturn.il | 12 +++++------ .../CovariantReturns/UnitTest/UnitTest.il | 12 +++++------ .../UnitTest/UnitTestDelegates.il | 12 +++++------ .../CovariantReturns/UnitTest/UnitTest_GVM.il | 12 +++++------ .../System.Private.CoreLib.Shared.projitems | 2 +- ...e.cs => PreserveBaseOverridesAttribute.cs} | 4 ++-- .../System.Runtime/ref/System.Runtime.cs | 6 +++--- 13 files changed, 58 insertions(+), 58 deletions(-) rename src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/{RequireMethodImplToRemainInEffectAttribute.cs => PreserveBaseOverridesAttribute.cs} (59%) diff --git a/docs/design/features/covariant-return-methods.md b/docs/design/features/covariant-return-methods.md index dd7a1d28d47222..3c9ac8c4db890c 100644 --- a/docs/design/features/covariant-return-methods.md +++ b/docs/design/features/covariant-return-methods.md @@ -12,7 +12,7 @@ If a language wishes for the override to be semantically visible such that users For virtual method slot MethodImpl overrides, each slot shall be checked for compatible signature on type load. (Implementation note: This behavior can be triggered only if the type has a covariant return type override in its hierarchy, so as to make this pay for play.) -A new `RequireMethodImplToRemainInEffectAttribute` shall be added. The presence of this attribute is to require the type loader to ensure that the MethodImpl records specified on the method have not lost their slot unifying behavior due to other actions. This is used to allow the C# language to require that overrides have the consistent behaviors expected. The expectation is that C# would place this attribute on covariant override methods in classes. +A new `PreserveBaseOverridesAttribute` shall be added. The presence of this attribute is to require the type loader to ensure that the MethodImpl records specified on the method have not lost their slot unifying behavior due to other actions. This is used to allow the C# language to require that overrides have the consistent behaviors expected. The expectation is that C# would place this attribute on covariant override methods in classes. ## Implementation Notes @@ -31,7 +31,7 @@ Once a method is flagged for return type checking, every time the vtable slot co ### VTable Slot Unification -If a MethodImpl has the `RequireMethodImplToRemainInEffectAttribute` attribute, it needs to propagate all applicable vtable slots on the type. This is to ensure that if we use the signature of one of the base type methods to call the overriding method, we still execute the overriding method. +If a MethodImpl has the `PreserveBaseOverridesAttribute` attribute, it needs to propagate all applicable vtable slots on the type. This is to ensure that if we use the signature of one of the base type methods to call the overriding method, we still execute the overriding method. Consider this case: ``` C# @@ -39,11 +39,11 @@ Consider this case: RetType VirtualFunction() { } } class B : A { - [RequireMethodImplToRemainInEffect] + [PreserveBaseOverrides] DerivedRetType VirtualFunction() { .override A.VirtualFuncion } } class C : B { - [RequireMethodImplToRemainInEffect] + [PreserveBaseOverrides] MoreDerivedRetType VirtualFunction() { .override A.VirtualFunction } } ``` diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs index acc8f2b618cc7e..10b2edb0abdce5 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs @@ -416,10 +416,10 @@ public static bool ContainsSignatureVariables(this TypeDesc thisType) /// Check if MethodImpl requires slot unification. /// /// Method to check - /// True when the method is marked with the RequireMethodImplToRemainInEffect custom attribute, false otherwise. + /// True when the method is marked with the PreserveBaseOverrides custom attribute, false otherwise. public static bool RequiresSlotUnification(this MethodDesc method) { - if (method.HasCustomAttribute("System.Runtime.CompilerServices", "RequireMethodImplToRemainInEffectAttribute")) + if (method.HasCustomAttribute("System.Runtime.CompilerServices", "PreserveBaseOverridesAttribute")) { #if DEBUG // We shouldn't be calling this for non-MethodImpls, so verify that the method being checked is really a MethodImpl diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index 1a5a764a33d94d..bd13819169c409 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/src/vm/class.cpp @@ -981,14 +981,14 @@ void ClassLoader::LoadExactParents(MethodTable *pMT) /*static*/ bool ClassLoader::IsCompatibleWith(TypeHandle hType1, TypeHandle hType2) { - // Structs can be casted to the interfaces they implement, but they are not compatible according to ECMA I.8.7.1 + // Structs can be cast to the interfaces they implement, but they are not compatible according to ECMA I.8.7.1 bool isCastFromValueTypeToReferenceType = hType2.IsValueType() && !hType1.IsValueType(); if (isCastFromValueTypeToReferenceType) { return false; } - // Nullable can be casted to T, but this is not compatible according to ECMA I.8.7.1 + // Nullable can be cast to T, but this is not compatible according to ECMA I.8.7.1 bool isCastFromNullableOfTtoT = hType1.GetMethodTable()->IsNullable() && hType2.IsEquivalentTo(hType1.GetMethodTable()->GetInstantiation()[0]); if (isCastFromNullableOfTtoT) { @@ -1019,7 +1019,7 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) // ECMA I.8.7.1, which is what the CanCastTo() API checks. // // The second step is to propagate an overriding MethodImpl to all applicable vtable slots if the MethodImpl - // has the RequireMethodImplToRemainInEffect attribute. This is to ensure that if we use the signature of one of + // has the PreserveBaseOverrides attribute. This is to ensure that if we use the signature of one of // the base type methods to call the overriding method, we still execute the overriding method. // // Consider this case: @@ -1028,7 +1028,7 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) // RetType VirtualFunction() { } // } // class B : A { - // [RequireMethodImplToRemainInEffect] + // [PreserveBaseOverrides] // DerivedRetType VirtualFunction() { .override A.VirtualFuncion } // } // class C : B { @@ -1142,7 +1142,7 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT) { BYTE* pVal = NULL; ULONG cbVal = 0; - if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::RequireMethodImplToRemainInEffectAttribute, (const void**)&pVal, &cbVal) == S_OK) + if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::PreserveBaseOverridesAttribute, (const void**)&pVal, &cbVal) == S_OK) foundAttribute = true; } diff --git a/src/coreclr/src/vm/wellknownattributes.h b/src/coreclr/src/vm/wellknownattributes.h index c5bbcc5d4279a2..a853461b02147d 100644 --- a/src/coreclr/src/vm/wellknownattributes.h +++ b/src/coreclr/src/vm/wellknownattributes.h @@ -35,7 +35,7 @@ enum class WellKnownAttribute : DWORD UnmanagedFunctionPointer, ThreadStatic, WinRTMarshalingBehaviorAttribute, - RequireMethodImplToRemainInEffectAttribute, + PreserveBaseOverridesAttribute, CountOfWellKnownAttributes }; @@ -100,8 +100,8 @@ inline const char *GetWellKnownAttributeName(WellKnownAttribute attribute) return "System.ThreadStaticAttribute"; case WellKnownAttribute::WinRTMarshalingBehaviorAttribute: return "Windows.Foundation.Metadata.MarshalingBehaviorAttribute"; - case WellKnownAttribute::RequireMethodImplToRemainInEffectAttribute: - return "System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute"; + case WellKnownAttribute::PreserveBaseOverridesAttribute: + return "System.Runtime.CompilerServices.PreserveBaseOverridesAttribute"; case WellKnownAttribute::CountOfWellKnownAttributes: default: break; // Silence compiler warnings diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il index d93298c6ae699a..5afa5155a755ab 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/Interfaces/UnitTest.il @@ -160,7 +160,7 @@ .method public hidebysig newslot virtual instance class INonGenThroughGen2 NonGenThroughGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -171,7 +171,7 @@ .method public hidebysig newslot virtual instance class IGenToNonGen1> GenToNonGen(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -182,7 +182,7 @@ .method public hidebysig newslot virtual instance class INonGenericDerived1 MyGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -193,7 +193,7 @@ .method public hidebysig newslot virtual instance class IGenDerive1> MyGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -255,7 +255,7 @@ .method public hidebysig newslot virtual instance class IGenRetType MyFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -266,7 +266,7 @@ .method public hidebysig newslot virtual instance class IC MyFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -277,7 +277,7 @@ .method public hidebysig newslot virtual instance class ICovariant MyFuncCovariant(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -288,7 +288,7 @@ .method public hidebysig newslot virtual instance class IContravariant MyFuncContravariant(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -428,7 +428,7 @@ .method public hidebysig newslot virtual instance class IVariant MultiLevelGenericVariantFunc(string&) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -480,7 +480,7 @@ .method public hidebysig newslot virtual instance class IVariant MultiLevelGenericVariantFunc(string&) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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 diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il index e920a66bbfb1ab..da7e5144dd925d 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/AttributeTesting.il @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -// This test validates the behavior in the presence/absence of the RequireMethodImplToRemainInEffectAttribute. +// 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) @@ -57,7 +57,7 @@ .method public hidebysig newslot virtual instance string Func1() { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) ldstr "T1" ret } @@ -250,7 +250,7 @@ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .method public hidebysig newslot virtual instance string Func2() { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance string class C.T1::Func1() ldstr "T2" ret @@ -321,7 +321,7 @@ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .method public hidebysig virtual instance string Func1() { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) ldstr "T2" ret } diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il index cc28520ffb56ed..c5e108029e7e2e 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/OverrideMoreDerivedReturn.il @@ -268,7 +268,7 @@ { .method public hidebysig newslot virtual instance class NonGenThroughGen5 NonGenThroughGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldarg.1 ldstr "NonGenThroughGen5 DerivedTestType.NonGenThroughGenFunc()" @@ -279,7 +279,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen4 GenToNonGen(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 ldstr "GenToNonGen4 DerivedTestType.GenToNonGen()" @@ -290,7 +290,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived5 MyGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "NonGenericDerived5 DerivedTestType.MyGenFunc()" @@ -301,7 +301,7 @@ .method public hidebysig newslot virtual instance class GenDerive4 MyGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "GenDerive4 DerivedTestType.MyGenFunc()" @@ -312,7 +312,7 @@ .method public hidebysig newslot virtual instance class GenDerivedRetType2 MyFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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 "GenDerivedRetType2 DerivedTestType.MyFunc()" @@ -323,7 +323,7 @@ .method public hidebysig newslot virtual instance class D MyFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc(string& res) ldarg.1 ldstr "D DerivedTestType.MyFunc()" diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il index 950ec5c9120ad6..ec1022254d0fc0 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest.il @@ -164,7 +164,7 @@ .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldarg.1 ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" @@ -175,7 +175,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGen(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 ldstr "GenToNonGen1> GenMiddleType.GenToNonGen()" @@ -186,7 +186,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived1 MyGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "NonGenericDerived1 GenMiddleType.MyGenFunc()" @@ -197,7 +197,7 @@ .method public hidebysig newslot virtual instance class GenDerive1> MyGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "GenDerive1> GenMiddleType.MyGenFunc()" @@ -259,7 +259,7 @@ .method public hidebysig newslot virtual instance class GenRetType MyFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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 "GenRetType TestType.MyFunc()" @@ -270,7 +270,7 @@ .method public hidebysig newslot virtual instance class C MyFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc(string& res) ldarg.1 ldstr "C TestType.MyFunc()" diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il index 1fec32baeb3628..6d76c7d27f3db1 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTestDelegates.il @@ -177,7 +177,7 @@ .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::NonGenThroughGenFunc(string& res) ldarg.1 ldstr "NonGenThroughGen2 GenMiddleType.NonGenThroughGenFunc()" @@ -188,7 +188,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGen(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::GenToNonGen(string& res) ldarg.1 ldstr "GenToNonGen1> GenMiddleType.GenToNonGen()" @@ -199,7 +199,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived1 MyGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "NonGenericDerived1 GenMiddleType.MyGenFunc()" @@ -210,7 +210,7 @@ .method public hidebysig newslot virtual instance class GenDerive1> MyGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class GenRetType> class GenBaseType::MyGenFunc(string& res) ldarg.1 ldstr "GenDerive1> GenMiddleType.MyGenFunc()" @@ -272,7 +272,7 @@ .method public hidebysig newslot virtual instance class GenRetType MyFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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 "GenRetType TestType.MyFunc()" @@ -283,7 +283,7 @@ .method public hidebysig newslot virtual instance class C MyFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.PreserveBaseOverridesAttribute::.ctor() = (01 00 00 00) .override method instance class B class GenBaseType::MyFunc(string& res) ldarg.1 ldstr "C TestType.MyFunc()" diff --git a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il index 8f9e4933414e20..75bcddd5de63e8 100644 --- a/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il +++ b/src/coreclr/tests/src/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/UnitTest_GVM.il @@ -173,7 +173,7 @@ .method public hidebysig newslot virtual instance class NonGenThroughGen2 NonGenThroughGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -184,7 +184,7 @@ .method public hidebysig newslot virtual instance class GenToNonGen1> GenToNonGen(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -195,7 +195,7 @@ .method public hidebysig newslot virtual instance class NonGenericDerived1 MyGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -206,7 +206,7 @@ .method public hidebysig newslot virtual instance class GenDerive1> MyGenFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -265,7 +265,7 @@ .method public hidebysig newslot virtual instance class GenRetType MyFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" @@ -276,7 +276,7 @@ .method public hidebysig newslot virtual instance class C MyFunc(string& res) { - .custom instance void [System.Runtime]System.Runtime.CompilerServices.RequireMethodImplToRemainInEffectAttribute::.ctor() = (01 00 00 00) + .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()" diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 03a793d83184b2..85538c671c8ab2 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -633,7 +633,7 @@ - + diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RequireMethodImplToRemainInEffectAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/PreserveBaseOverridesAttribute.cs similarity index 59% rename from src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RequireMethodImplToRemainInEffectAttribute.cs rename to src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/PreserveBaseOverridesAttribute.cs index 91d7d2f02f7373..6f45c2d95a23cf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RequireMethodImplToRemainInEffectAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/PreserveBaseOverridesAttribute.cs @@ -4,8 +4,8 @@ namespace System.Runtime.CompilerServices { - [AttributeUsageAttribute(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] - public sealed class RequireMethodImplToRemainInEffectAttribute : Attribute + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] + public sealed class PreserveBaseOverridesAttribute : Attribute { } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 08b0243639ba6a..9a51bfe8e107ec 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -9151,10 +9151,10 @@ public void OnCompleted(System.Action continuation) { } public void UnsafeOnCompleted(System.Action continuation) { } } } - [System.AttributeUsageAttribute(System.AttributeTargets.Method, Inherited = false, AllowMultiple = false)] - public sealed partial class RequireMethodImplToRemainInEffectAttribute : System.Attribute + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] + public sealed class PreserveBaseOverridesAttribute : Attribute { - public RequireMethodImplToRemainInEffectAttribute() { } + public PreserveBaseOverridesAttribute() {} } } namespace System.Runtime.ConstrainedExecution From 7ccd3ed7a9c775ebc214790a4d871282d389bd97 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Mon, 1 Jun 2020 12:35:08 +0200 Subject: [PATCH 21/21] Disable covariant returns tests on Mono for now The mono doesn't implement the feature yet --- src/coreclr/tests/issues.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 2a2f6dc840cdbe..b3b6ef5e21caef 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -1622,6 +1622,9 @@ needs triage + + needs triage + needs triage