[runtime] Handle custom attributes with nested array of enums. Fixes #13767
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 20 Aug 2013 22:31:43 +0000 (18:31 -0400)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 20 Aug 2013 22:34:08 +0000 (18:34 -0400)
When decoding a custom attribute value, an array value in an object
position can have type of an enum.

mcs/class/corlib/Test/System/TypeTest.cs
mono/metadata/reflection.c

index 3bbe3cde42adc064d1e426fe476fdb3fb1042eba..ae15644df19219c281c22886985e2108f5524cdb 100644 (file)
@@ -2512,6 +2512,47 @@ PublicKeyToken=b77a5c561934e089"));
                        Assert.IsFalse (typeof (bug82431B4).IsDefined (typeof (NotInheritAttribute), true), "#K4");
                }
 
+               class Bug13767Attribute : Attribute
+               {
+                       public object[] field;
+
+                       public Bug13767Attribute (params object[] args)
+                       {
+                               field = args;
+                       }
+               }
+
+               public enum Bug13767Enum
+               {
+                       Value0,
+                       Value1,
+               }
+
+               [Bug13767("Demo", new[] { Bug13767Enum.Value1, Bug13767Enum.Value0 })]
+               public void Bug13767Method(string attributeName, MyEnum[]options)
+               {
+
+               }
+
+               [Test] //Bug 13767
+               public void CustomAttributeWithNestedArrayOfEnum ()
+               {
+                       var m = GetType ().GetMethod ("Bug13767Method");
+
+                       var attr = m.GetCustomAttributes (false);
+                       Assert.AreEqual (1, attr.Length, "#1");
+
+                       var tc = (Bug13767Attribute)attr[0];
+                       Assert.AreEqual (2, tc.field.Length, "#2");
+                       Assert.AreEqual ("Demo", tc.field[0], "#3");
+                       Assert.IsNotNull (tc.field[1], "#4");
+
+                       var arr = (Bug13767Enum[])tc.field [1];
+                       Assert.AreEqual (2, arr.Length, "#5");
+                       Assert.AreEqual (Bug13767Enum.Value1, arr [0], "#6");
+                       Assert.AreEqual (Bug13767Enum.Value0, arr [1], "#7");
+               }
+
                [Test] // GetType (String)
                public void GetType1_TypeName_Null ()
                {
index 993669915328e19d944d20038d30c2371c980757..66f5590f7a98896097f686f4a14c182f16575d98 100644 (file)
@@ -7774,6 +7774,23 @@ mono_reflection_get_token (MonoObject *obj)
        return token;
 }
 
+static MonoClass*
+load_cattr_enum_type (MonoImage *image, const char *p, const char **end)
+{
+       char *n;
+       MonoType *t;
+       int slen = mono_metadata_decode_value (p, &p);
+       n = g_memdup (p, slen + 1);
+       n [slen] = 0;
+       t = mono_reflection_type_from_name (n, image);
+       if (!t)
+               g_error ("Cannot load type '%s'", n);
+       g_free (n);
+       p += slen;
+       *end = p;
+       return mono_class_from_mono_type (t);
+}
+
 static void*
 load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char **end)
 {
@@ -7892,6 +7909,8 @@ handle_type:
                        type = MONO_TYPE_SZARRAY;
                        if (etype == 0x50) {
                                tklass = mono_defaults.systemtype_class;
+                       } else if (etype == 0x55) {
+                               tklass = load_cattr_enum_type (image, p, &p);
                        } else {
                                if (etype == 0x51)
                                        /* See Partition II, Appendix B3 */