@@ -2973,6 +2973,23 @@ ves_icall_RuntimeType_GetInterfaces (MonoReflectionTypeHandle ref_type, MonoErro
29732973 return NULL_HANDLE_ARRAY ;
29742974}
29752975
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+
29762993static gboolean
29772994set_interface_map_data_method_object (MonoDomain * domain , MonoMethod * method , MonoClass * iclass , int ioffset , MonoClass * klass , MonoArrayHandle targets , MonoArrayHandle methods , int i , MonoError * error )
29782995{
@@ -3006,9 +3023,25 @@ set_interface_map_data_method_object (MonoDomain *domain, MonoMethod *method, Mo
30063023 }
30073024 }
30083025
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 ))))
30103034 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 {
30123045 MONO_HANDLE_ASSIGN (member , mono_method_get_object_handle (domain , foundMethod , mono_class_is_interface (foundMethod -> klass ) ? foundMethod -> klass : klass , error ));
30133046 goto_if_nok (error , leave );
30143047 MONO_HANDLE_ARRAY_SETREF (targets , i , member );
0 commit comments