2009-12-16 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Wed, 16 Dec 2009 19:41:24 +0000 (19:41 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Wed, 16 Dec 2009 19:41:24 +0000 (19:41 -0000)
* reflection.c (mono_type_get_object): If the type is VAR or MVAR check
if the owner class has not been finished before returning reflection_info.

Fixes #565127.

svn path=/trunk/mono/; revision=148575

mono/metadata/ChangeLog
mono/metadata/reflection.c

index 66c38c602f7ba765fa61e1aa7bdbf9545658c72f..be3299f53321fe351a57f3651c124ba44ad08fea 100644 (file)
@@ -1,3 +1,10 @@
+2009-12-16  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * reflection.c (mono_type_get_object): If the type is VAR or MVAR check
+       if the owner class has not been finished before returning reflection_info.      
+
+       Fixes #565127.
+
 2009-12-16  Zoltan Varga  <vargaz@gmail.com>
 
        * reflection.c (mono_custom_attrs_from_param): Avoid a crash if a dynamic
index c9113e7c5deda9c66120f4cfbef2643eebca8fbb..f94fdab5bde541631c8c4c73d0c57e93e4b24585 100644 (file)
@@ -6377,9 +6377,28 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
        }
 
        if (klass->reflection_info && !klass->wastypebuilder) {
+               gboolean is_type_done = TRUE;
+               /* Generic parameters have reflection_info set but they are not finished together with their enclosing type.
+                * We must ensure that once a type is finished we don't return a GenericTypeParameterBuilder.
+                * We can't simply close the types as this will interfere with other parts of the generics machinery.
+               */
+               if (klass->byval_arg.type == MONO_TYPE_MVAR || klass->byval_arg.type == MONO_TYPE_VAR) {
+                       MonoGenericParam *gparam = klass->byval_arg.data.generic_param;
+
+                       if (gparam->owner && gparam->owner->is_method) {
+                               MonoMethod *method = gparam->owner->owner.method;
+                               if (mono_class_get_generic_type_definition (method->klass)->wastypebuilder)
+                                       is_type_done = FALSE;
+                       } else if (gparam->owner && !gparam->owner->is_method) {
+                               MonoClass *klass = gparam->owner->owner.klass;
+                               if (mono_class_get_generic_type_definition (klass)->wastypebuilder)
+                                       is_type_done = FALSE;
+                       }
+               } 
+
                /* g_assert_not_reached (); */
                /* should this be considered an error condition? */
-               if (!type->byref) {
+               if (is_type_done && !type->byref) {
                        mono_domain_unlock (domain);
                        mono_loader_unlock ();
                        return klass->reflection_info;