When encoding a memberref to a field of a generic instance we must use the type of...
authorRodrigo Kumpera <kumpera@gmail.com>
Thu, 7 Feb 2013 23:55:47 +0000 (18:55 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Fri, 8 Feb 2013 00:22:14 +0000 (19:22 -0500)
* reflection.c (mono_image_get_fieldref_token): We must encode the memberref using the GTD type so
we can distinguish between the following two:

class Foo<T> {
T t;
int t;
}

The above two fields for the instance Foo<int> must be encoded as "!0 Foo<int>:t" and "int Foo<int>:t"
respectively. The CLR does both structural and nominal matching on memberref resolution, so we must be
strict.

The previous fix removed tried to work-around a crash in the generic instance case due to the field
type been null. This now happens because field types are lazily loaded and must always be looked up
using mono_field_get_type. The original code code was not and so broken.

mono/metadata/reflection.c

index 2a61a9c067fbe58e04a55a83de2aa2603be7c8ed..50f5d2cb2d8053c971ea8e900632edc5d5fb94d6 100644 (file)
@@ -2750,10 +2750,15 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoCl
        if (token)
                return token;
 
-       if (is_field_on_inst (field))
-               type = get_field_on_inst_generic_type (field);
-       else
-               type = mono_field_get_type (field);
+       if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
+               int index = field - field->parent->fields;
+               type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
+       } else {
+               if (is_field_on_inst (field))
+                       type = get_field_on_inst_generic_type (field);
+               else
+                       type = mono_field_get_type (field);
+       }
        token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
                                                                                        mono_field_get_name (field),
                                                                                        fieldref_encode_signature (assembly, field->parent->image, type));