Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:netway:mono58
mono
mono-12802.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File mono-12802.diff of Package mono
diff --git a/mono/metadata/class-init.c b/mono/metadata/class-init.c index 670446618186..802bd8d96855 100644 --- a/mono/metadata/class-init.c +++ b/mono/metadata/class-init.c @@ -1410,13 +1410,15 @@ print_implemented_interfaces (MonoClass *klass) printf ("Packed interface table for class %s has size %d\n", name, klass->interface_offsets_count); g_free (name); - for (i = 0; i < klass->interface_offsets_count; i++) - printf (" [%03d][UUID %03d][SLOT %03d][SIZE %03d] interface %s.%s\n", i, + for (i = 0; i < klass->interface_offsets_count; i++) { + char *ic_name = mono_type_get_full_name (klass->interfaces_packed [i]); + printf (" [%03d][UUID %03d][SLOT %03d][SIZE %03d] interface %s\n", i, klass->interfaces_packed [i]->interface_id, klass->interface_offsets_packed [i], mono_class_get_method_count (klass->interfaces_packed [i]), - klass->interfaces_packed [i]->name_space, - klass->interfaces_packed [i]->name ); + ic_name); + g_free (ic_name); + } printf ("Interface flags: "); for (i = 0; i <= klass->max_interface_id; i++) if (MONO_CLASS_IMPLEMENTS_INTERFACE (klass, i)) @@ -2675,6 +2677,55 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter) } } +static void +print_vtable_layout_result (MonoClass *klass, MonoMethod **vtable, int cur_slot) +{ + int i, icount = 0; + + print_implemented_interfaces (klass); + + for (i = 0; i <= klass->max_interface_id; i++) + if (MONO_CLASS_IMPLEMENTS_INTERFACE (klass, i)) + icount++; + + printf ("VTable %s (vtable entries = %d, interfaces = %d)\n", mono_type_full_name (m_class_get_byval_arg (klass)), + klass->vtable_size, icount); + + for (i = 0; i < cur_slot; ++i) { + MonoMethod *cm; + + cm = vtable [i]; + if (cm) { + printf (" slot assigned: %03d, slot index: %03d %s\n", i, cm->slot, + mono_method_full_name (cm, TRUE)); + } else { + printf (" slot assigned: %03d, <null>\n", i); + } + } + + + if (icount) { + printf ("Interfaces %s.%s (max_iid = %d)\n", klass->name_space, + klass->name, klass->max_interface_id); + + for (i = 0; i < klass->interface_count; i++) { + MonoClass *ic = klass->interfaces [i]; + printf (" slot offset: %03d, method count: %03d, iid: %03d %s\n", + mono_class_interface_offset (klass, ic), + count_virtual_methods (ic), ic->interface_id, mono_type_full_name (m_class_get_byval_arg (ic))); + } + + for (MonoClass *k = klass->parent; k ; k = k->parent) { + for (i = 0; i < k->interface_count; i++) { + MonoClass *ic = k->interfaces [i]; + printf (" parent slot offset: %03d, method count: %03d, iid: %03d %s\n", + mono_class_interface_offset (klass, ic), + count_virtual_methods (ic), ic->interface_id, mono_type_full_name (m_class_get_byval_arg (ic))); + } + } + } +} + /* * LOCKING: this is supposed to be called with the loader lock held. */ @@ -2685,7 +2736,6 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o MonoClass *k, *ic; MonoMethod **vtable = NULL; int i, max_vtsize = 0, cur_slot = 0; - guint32 max_iid; GPtrArray *ifaces = NULL; GHashTable *override_map = NULL; GHashTable *override_class_map = NULL; @@ -2747,7 +2797,6 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o if (cur_slot == -1) /*setup_interface_offsets fails the type.*/ return; - max_iid = klass->max_interface_id; DEBUG_INTERFACE_VTABLE (first_non_interface_slot = cur_slot); /* Optimized version for generic instances */ @@ -2784,6 +2833,9 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o klass->methods [i]->slot = gklass->methods [i]->slot; } + if (mono_print_vtable) + print_vtable_layout_result (klass, klass->vtable, gklass->vtable_size); + return; } @@ -3152,6 +3204,10 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o mono_class_set_type_load_failure (klass, "Type %s has invalid vtable method slot %d with method %s", type_name, i, method_name); g_free (type_name); g_free (method_name); + + if (mono_print_vtable) + print_vtable_layout_result (klass, vtable, cur_slot); + g_free (vtable); return; } @@ -3183,50 +3239,8 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o } DEBUG_INTERFACE_VTABLE (print_vtable_full (klass, klass->vtable, klass->vtable_size, first_non_interface_slot, "FINALLY", FALSE)); - if (mono_print_vtable) { - int icount = 0; - - print_implemented_interfaces (klass); - - for (i = 0; i <= max_iid; i++) - if (MONO_CLASS_IMPLEMENTS_INTERFACE (klass, i)) - icount++; - - printf ("VTable %s (vtable entries = %d, interfaces = %d)\n", mono_type_full_name (m_class_get_byval_arg (klass)), - klass->vtable_size, icount); - - for (i = 0; i < cur_slot; ++i) { - MonoMethod *cm; - - cm = vtable [i]; - if (cm) { - printf (" slot assigned: %03d, slot index: %03d %s\n", i, cm->slot, - mono_method_full_name (cm, TRUE)); - } - } - - - if (icount) { - printf ("Interfaces %s.%s (max_iid = %d)\n", klass->name_space, - klass->name, max_iid); - - for (i = 0; i < klass->interface_count; i++) { - ic = klass->interfaces [i]; - printf (" slot offset: %03d, method count: %03d, iid: %03d %s\n", - mono_class_interface_offset (klass, ic), - count_virtual_methods (ic), ic->interface_id, mono_type_full_name (m_class_get_byval_arg (ic))); - } - - for (k = klass->parent; k ; k = k->parent) { - for (i = 0; i < k->interface_count; i++) { - ic = k->interfaces [i]; - printf (" parent slot offset: %03d, method count: %03d, iid: %03d %s\n", - mono_class_interface_offset (klass, ic), - count_virtual_methods (ic), ic->interface_id, mono_type_full_name (m_class_get_byval_arg (ic))); - } - } - } - } + if (mono_print_vtable) + print_vtable_layout_result (klass, vtable, cur_slot); g_free (vtable); @@ -3242,6 +3256,10 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o mono_class_set_type_load_failure (klass, "VTable setup of type %s failed", name); mono_error_cleanup (error); g_free (name); + if (mono_print_vtable) + print_vtable_layout_result (klass, vtable, cur_slot); + + g_free (vtable); if (override_map) g_hash_table_destroy (override_map); @@ -4069,7 +4087,7 @@ mono_get_unique_iid (MonoClass *klass) } else { generic_id = 0; } - printf ("Interface: assigned id %d to %s|%s|%d\n", iid, klass->image->name, type_name, generic_id); + printf ("Interface: assigned id %d to %s|%s|%d\n", iid, klass->image->assembly_name, type_name, generic_id); g_free (type_name); } #endif diff --git a/mono/metadata/class.c b/mono/metadata/class.c index 7a39e6197aff..e73324de4c7b 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -644,7 +644,7 @@ inflate_generic_type (MonoImage *image, MonoType *type, MonoGenericContext *cont * while the VAR/MVAR duplicates a type from the context. So, we need to ensure that the * ->byref and ->attrs from @type are propagated to the returned type. */ - nt = mono_metadata_type_dup (image, inst->type_argv [num]); + nt = mono_metadata_type_dup_with_cmods (image, inst->type_argv [num], type); nt->byref = type->byref; nt->attrs = type->attrs; return nt; @@ -667,7 +667,7 @@ inflate_generic_type (MonoImage *image, MonoType *type, MonoGenericContext *cont num, pname ? pname : "", inst->type_argv [num]->type); return NULL; } - nt = mono_metadata_type_dup (image, inst->type_argv [num]); + nt = mono_metadata_type_dup_with_cmods (image, inst->type_argv [num], type); nt->byref = type->byref; nt->attrs = type->attrs; return nt; @@ -790,7 +790,7 @@ mono_class_inflate_generic_type_with_mempool (MonoImage *image, MonoType *type, if (!inflated) { MonoType *shared = mono_metadata_get_shared_type (type); - if (shared) { + if (shared && !type->has_cmods) { return shared; } else { return mono_metadata_type_dup (image, type); diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h index 05ceefcc4bfd..18dd66a78a77 100644 --- a/mono/metadata/metadata-internals.h +++ b/mono/metadata/metadata-internals.h @@ -894,6 +894,8 @@ void mono_unload_interface_ids (MonoBitSet *bitset); MonoType *mono_metadata_type_dup (MonoImage *image, const MonoType *original); +MonoType *mono_metadata_type_dup_with_cmods (MonoImage *image, const MonoType *original, const MonoType *cmods_source); + MonoMethodSignature *mono_metadata_signature_dup_full (MonoImage *image,MonoMethodSignature *sig); MonoMethodSignature *mono_metadata_signature_dup_mempool (MonoMemPool *mp, MonoMethodSignature *sig); MonoMethodSignature *mono_metadata_signature_dup_add_this (MonoImage *image, MonoMethodSignature *sig, MonoClass *klass); diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index 4a9586b79217..5fb478a6b62d 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -5698,13 +5698,28 @@ mono_metadata_signature_equal (MonoMethodSignature *sig1, MonoMethodSignature *s */ MonoType * mono_metadata_type_dup (MonoImage *image, const MonoType *o) +{ + return mono_metadata_type_dup_with_cmods (image, o, o); +} + +/** + * Works the same way as mono_metadata_type_dup but pick cmods from @cmods_source + */ +MonoType * +mono_metadata_type_dup_with_cmods (MonoImage *image, const MonoType *o, const MonoType *cmods_source) { MonoType *r = NULL; - size_t sizeof_o = mono_sizeof_type (o); + size_t sizeof_o = mono_sizeof_type (cmods_source); r = image ? (MonoType *)mono_image_alloc0 (image, sizeof_o) : (MonoType *)g_malloc (sizeof_o); - memcpy (r, o, sizeof_o); + if (cmods_source->has_cmods) { + g_assert (!image || image == mono_type_get_cmods (cmods_source)->image); + memcpy (r, cmods_source, sizeof_o); + } + + memcpy (r, o, sizeof (MonoType)); + r->has_cmods = cmods_source->has_cmods; if (o->type == MONO_TYPE_PTR) { r->data.type = mono_metadata_type_dup (image, o->data.type); diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am index 780acdb545f6..25ee74b34d80 100755 --- a/mono/tests/Makefile.am +++ b/mono/tests/Makefile.am @@ -694,7 +694,8 @@ TESTS_CS_SRC= \ nested_type_visibility.cs \ dynamic-method-churn.cs \ verbose.cs \ - generic-unmanaged-constraint.cs + generic-unmanaged-constraint.cs \ + bug-10834.cs # some tests fail to compile on mcs if CSC_IS_ROSLYN diff --git a/mono/tests/bug-10834.cs b/mono/tests/bug-10834.cs new file mode 100644 index 000000000000..26b07d761196 --- /dev/null +++ b/mono/tests/bug-10834.cs @@ -0,0 +1,73 @@ +using System; +using System.Reflection; + +namespace Repro { + class Program + { + static bool Check (Type t) + { + Console.WriteLine ($"--- {t}"); + + var m = t.GetMethod ("M1"); + Console.WriteLine (m); + + foreach(var p in m.GetParameters ()) + Console.WriteLine ($"{p}: {p.ParameterType} / {p.GetRequiredCustomModifiers().Length}"); + + Console.WriteLine (); + return m.GetParameters()[0].GetRequiredCustomModifiers().Length == 1; + } + + static int Main(string[] args) + { + if (!Check (typeof (C<>))) + return 1; + if (!Check (typeof (C<S1>))) + return 2; + + var o = new Bug (); + int res = o.M1 (new S1 ()); + Console.WriteLine (res); + if (res != 0) + return 3; + Console.WriteLine ("All good"); + return 0; + } + } + abstract class C<U> + { + public abstract int M1<T>(in T arg) where T : U, I1; + } + + class Bug : C<S1> + { + public override int M1<T2> (in T2 arg) + { + Console.WriteLine ("C<S1>::M1"); + arg.M3(); + return arg.M4(); + } + } + + interface I1 + { + void M3(); + int M4(); + } + + public struct S1: I1 + { + public int field; + public void M3 () + { + Console.WriteLine ("S1:M3"); + field = 42; + } + + public int M4() { + Console.WriteLine ("S1:M4 {0}", field); + + return field; + } + } +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor