@@ -2973,6 +2973,23 @@ ves_icall_RuntimeType_GetInterfaces (MonoReflectionTypeHandle ref_type, MonoErro
2973
2973
return NULL_HANDLE_ARRAY ;
2974
2974
}
2975
2975
2976
+ static gboolean
2977
+ method_is_reabstracted (MonoMethod * method )
2978
+ {
2979
+ /* only on interfaces */
2980
+ /* method is marked "final abstract" */
2981
+ /* FIXME: we need some other way to detect reabstracted methods. "final" is an incidental detail of the spec. */
2982
+ return m_method_is_final (method ) && m_method_is_abstract (method );
2983
+ }
2984
+
2985
+ static gboolean
2986
+ method_is_dim (MonoMethod * method )
2987
+ {
2988
+ /* only valid on interface methods*/
2989
+ /* method is marked "virtual" but not "virtual abstract" */
2990
+ return m_method_is_virtual (method ) && !m_method_is_abstract (method );
2991
+ }
2992
+
2976
2993
static gboolean
2977
2994
set_interface_map_data_method_object (MonoDomain * domain , MonoMethod * method , MonoClass * iclass , int ioffset , MonoClass * klass , MonoArrayHandle targets , MonoArrayHandle methods , int i , MonoError * error )
2978
2995
{
@@ -3006,9 +3023,25 @@ set_interface_map_data_method_object (MonoDomain *domain, MonoMethod *method, Mo
3006
3023
}
3007
3024
}
3008
3025
3009
- if (foundMethod -> flags & METHOD_ATTRIBUTE_ABSTRACT )
3026
+ /*
3027
+ * if the iterface method is reabstracted, and either the found implementation method is abstract, or the found
3028
+ * implementation method is from another DIM (meaning neither klass nor any of its ancestor classes implemented
3029
+ * the method), then say the target method is null.
3030
+ */
3031
+ if (method_is_reabstracted (method ) &&
3032
+ (m_method_is_abstract (foundMethod ) ||
3033
+ (mono_class_is_interface (foundMethod -> klass ) && method_is_dim (foundMethod ))))
3010
3034
MONO_HANDLE_ARRAY_SETREF (targets , i , NULL_HANDLE );
3011
- else {
3035
+ else if (mono_class_is_interface (foundMethod -> klass ) && method_is_reabstracted (foundMethod ) && !m_class_is_abstract (klass )) {
3036
+ /* if the method we found is a reabstracted DIM method, but the class isn't abstract, return NULL */
3037
+ /*
3038
+ * (C# doesn't seem to allow constructing such types, it requires the whole class to be abstract - in
3039
+ * which case we are supposed to return the reabstracted interface method. But in IL we can make a
3040
+ * non-abstract class with reabstracted interface methods - which is supposed to fail with an
3041
+ * EntryPointNotFoundException at invoke time, but does not prevent the class from loading.)
3042
+ */
3043
+ MONO_HANDLE_ARRAY_SETREF (targets , i , NULL_HANDLE );
3044
+ } else {
3012
3045
MONO_HANDLE_ASSIGN (member , mono_method_get_object_handle (domain , foundMethod , mono_class_is_interface (foundMethod -> klass ) ? foundMethod -> klass : klass , error ));
3013
3046
goto_if_nok (error , leave );
3014
3047
MONO_HANDLE_ARRAY_SETREF (targets , i , member );
0 commit comments