return FALSE;
}
+static gboolean debug_check;
+
MonoClass *
mono_class_get_generic_type_definition (MonoClass *klass)
{
{
int access_level;
+ if (access_klass == member_klass)
+ return TRUE;
+
if (access_klass->image->assembly && access_klass->image->assembly->corlib_internal)
return TRUE;
gboolean
mono_method_can_access_method (MonoMethod *method, MonoMethod *called)
{
- int can = can_access_member (method->klass, called->klass, NULL, called->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK);
- if (!can) {
- MonoClass *nested = method->klass->nested_in;
- while (nested) {
- can = can_access_member (nested, called->klass, NULL, called->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK);
- if (can)
- return TRUE;
- nested = nested->nested_in;
- }
+ gboolean res = mono_method_can_access_method_full (method, called, NULL);
+ if (!res) {
+ printf ("FAILED TO VERIFY %s calling %s\n", mono_method_full_name (method, 1), mono_method_full_name (called, 1));
+ debug_check = TRUE;
+ mono_method_can_access_method_full (method, called, NULL);
+ debug_check = FALSE;
}
- /*
- * FIXME:
- * with generics calls to explicit interface implementations can be expressed
- * directly: the method is private, but we must allow it. This may be opening
- * a hole or the generics code should handle this differently.
- * Maybe just ensure the interface type is public.
- */
- if ((called->flags & METHOD_ATTRIBUTE_VIRTUAL) && (called->flags & METHOD_ATTRIBUTE_FINAL))
- return TRUE;
- return can;
+
+ return res;
}
/*
gboolean
mono_method_can_access_method_full (MonoMethod *method, MonoMethod *called, MonoClass *context_klass)
{
+ if (debug_check) printf ("CHECKING %s -> %s (%p)\n", mono_method_full_name (method, 1), mono_method_full_name (called, 1), context_klass);
MonoClass *access_class = method->klass;
MonoClass *member_class = called->klass;
int can = can_access_member (access_class, member_class, context_klass, called->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK);
if (!can) {
+ if (debug_check) printf ("\tcan_access_member failed\n");
MonoClass *nested = access_class->nested_in;
while (nested) {
can = can_access_member (nested, member_class, context_klass, called->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK);
break;
nested = nested->nested_in;
}
+ if (!can && debug_check) printf ("\tcan_access_member nest check failed\n");
}
if (!can)
return FALSE;
+ if (debug_check) printf ("\ttype checking %s(%p) -> %s(%p)\n",
+ mono_type_get_full_name (access_class), access_class,
+ mono_type_get_full_name (member_class), member_class);
can = can_access_type (access_class, member_class);
if (!can) {
+ if (debug_check) printf ("\tcan_access_type check failed\n");
MonoClass *nested = access_class->nested_in;
while (nested) {
can = can_access_type (nested, member_class);
break;
nested = nested->nested_in;
}
+ if (!can && debug_check) printf ("\tcan_access_type nest check failed\n");
}
if (!can)
if (called->is_inflated) {
MonoMethodInflated * infl = (MonoMethodInflated*)called;
- if (infl->context.method_inst && !can_access_instantiation (access_class, infl->context.method_inst))
+ if (infl->context.method_inst && !can_access_instantiation (access_class, infl->context.method_inst)) {
+ if (debug_check) printf ("\tginst check failed\n");
return FALSE;
+ }
}
return TRUE;