if (!is_valid_type_in_context (ctx, type)) {
char *str = mono_type_full_name (type);
ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Invalid generic type (%s%s) (argument out of range or %s is not generic) at 0x%04x",
- type->type == MONO_TYPE_VAR ? "!" : "!!",
+ str [0] == '!' ? "" : type->type == MONO_TYPE_VAR ? "!" : "!!",
str,
type->type == MONO_TYPE_VAR ? "class" : "method",
ctx->ip_offset),
return generic_icollection_class;
}
+static MonoClass*
+get_ireadonlylist_class (void)
+{
+ static MonoClass* generic_ireadonlylist_class = NULL;
+
+ if (generic_ireadonlylist_class == NULL)
+ generic_ireadonlylist_class = mono_class_from_name (mono_defaults.corlib,
+ "System.Collections.Generic", "IReadOnlyList`1");
+ return generic_ireadonlylist_class;
+}
+
+static MonoClass*
+get_ireadonlycollection_class (void)
+{
+ static MonoClass* generic_ireadonlycollection_class = NULL;
+
+ if (generic_ireadonlycollection_class == NULL)
+ generic_ireadonlycollection_class = mono_class_from_name (mono_defaults.corlib,
+ "System.Collections.Generic", "IReadOnlyCollection`1");
+ return generic_ireadonlycollection_class;
+}
+
static MonoClass*
inflate_class_one_arg (MonoClass *gtype, MonoClass *arg0)
{
if (mono_class_has_variant_generic_params (target)) {
if (MONO_CLASS_IS_INTERFACE (target)) {
+ if (MONO_CLASS_IS_INTERFACE (candidate) && mono_class_is_variant_compatible (target, candidate, TRUE))
+ return TRUE;
+
if (candidate->rank == 1) {
if (verifier_inflate_and_check_compat (target, mono_defaults.generic_ilist_class, candidate->element_class))
return TRUE;
return TRUE;
if (verifier_inflate_and_check_compat (target, get_ienumerable_class (), candidate->element_class))
return TRUE;
+ if (verifier_inflate_and_check_compat (target, get_ireadonlylist_class (), candidate->element_class))
+ return TRUE;
+ if (verifier_inflate_and_check_compat (target, get_ireadonlycollection_class (), candidate->element_class))
+ return TRUE;
} else {
MonoError error;
int i;
merge_stacks (VerifyContext *ctx, ILCodeDesc *from, ILCodeDesc *to, gboolean start, gboolean external)
{
MonoError error;
- int i, j, k;
+ int i, j;
stack_init (ctx, to);
if (start) {
continue;
}
+ /*Both slots are the same boxed valuetype. Simply copy it.*/
+ if (stack_slot_is_boxed_value (old_slot) &&
+ stack_slot_is_boxed_value (new_slot) &&
+ mono_metadata_type_equal (old_type, new_type)) {
+ copy_stack_value (new_slot, old_slot);
+ continue;
+ }
+
if (mono_type_is_generic_argument (old_type) || mono_type_is_generic_argument (new_type)) {
char *old_name = stack_slot_full_name (old_slot);
char *new_name = stack_slot_full_name (new_slot);
goto end_verify;
}
- for (j = 0; j < old_class->interface_count; ++j) {
- for (k = 0; k < new_class->interface_count; ++k) {
- if (mono_metadata_type_equal (&old_class->interfaces [j]->byval_arg, &new_class->interfaces [k]->byval_arg)) {
- match_class = old_class->interfaces [j];
- goto match_found;
- }
- }
- }
-
/* if old class is an interface that new class implements */
if (old_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
if (verifier_class_is_assignable_from (old_class, new_class)) {
ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Catch clause %d with invalid type", i));
break;
}
-
+ if (!mono_type_is_valid_in_context (&ctx, &clause->data.catch_class->byval_arg))
+ break;
+
init_stack_with_value_at_exception_boundary (&ctx, ctx.code + clause->handler_offset, clause->data.catch_class);
}
else if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
}
}
+ if (!ctx.valid)
+ goto cleanup;
+
original_bb = bb = mono_basic_block_split (method, &error);
if (!mono_error_ok (&error)) {
ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid branch target: %s", mono_error_get_message (&error)));
MonoClass *ctr = *constraints;
MonoType *constraint_type = &ctr->byval_arg;
+ if (!mono_class_can_access_class (class, ctr))
+ goto fail;
+
if (!mono_type_is_valid_type_in_context (constraint_type, &gc->context))
goto fail;