diff options
author | Aleksey Kliger (λgeek) <akliger@gmail.com> | 2017-04-29 00:45:37 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-29 00:45:37 +0300 |
commit | 1d0445bfc7d1d6e9eee7197bc29d4bcd7a60a1d5 (patch) | |
tree | 421533866f11c1596c8bd26c89e114f6a1a02390 | |
parent | 1d389ea02c79e397b9e2e14a0a42d430fd024e04 (diff) | |
parent | ad60bf18b7f42111cda55ffe0590f9134803b1c7 (diff) |
Merge pull request #4769 from lambdageek/bug-55681-2017-02mono-5.0.0.94
[sre-save] Handle ConstructorBuilder custom attribute constructors
-rw-r--r-- | mcs/class/corlib/Test/System.Reflection.Emit/CustomAttributeBuilderTest.cs | 55 | ||||
-rw-r--r-- | mono/metadata/sre-internals.h | 3 | ||||
-rw-r--r-- | mono/metadata/sre-save.c | 14 | ||||
-rw-r--r-- | mono/metadata/sre.c | 11 |
4 files changed, 79 insertions, 4 deletions
diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/CustomAttributeBuilderTest.cs b/mcs/class/corlib/Test/System.Reflection.Emit/CustomAttributeBuilderTest.cs index eb6eff866c6..c57616753f7 100644 --- a/mcs/class/corlib/Test/System.Reflection.Emit/CustomAttributeBuilderTest.cs +++ b/mcs/class/corlib/Test/System.Reflection.Emit/CustomAttributeBuilderTest.cs @@ -790,6 +790,61 @@ namespace MonoTests.System.Reflection.Emit Assert.IsInstanceOfType (typeof (PublicVisibleCustomAttribute), attrs[1]); Assert.IsInstanceOfType (typeof (PublicVisibleCustomAttribute), attrs[2]); } + + [Test] + public void CustomAttributeSameAssembly () { + // Regression test for 55681 + // + // We build: + // class MyAttr : Attr { public MyAttr () { } } + // [assembly:MyAttr()] + // + // the important bit is that we pass the ConstructorBuilder to the CustomAttributeBuilder + var assemblyName = new AssemblyName ("Repro55681"); + var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (assemblyName, AssemblyBuilderAccess.Save, tempDir); + var moduleBuilder = assemblyBuilder.DefineDynamicModule ("Repro55681", "Repro55681.dll"); + var typeBuilder = moduleBuilder.DefineType ("MyAttr", TypeAttributes.Public, typeof (Attribute)); + ConstructorBuilder ctor = typeBuilder.DefineDefaultConstructor (MethodAttributes.Public); + typeBuilder.CreateType (); + + assemblyBuilder.SetCustomAttribute (new CustomAttributeBuilder (ctor, new object [] { })); + + assemblyBuilder.Save ("Repro55681.dll"); + } + + [Test] + public void CustomAttributeAcrossAssemblies () { + // Regression test for 55681 + // + // We build: + // assembly1: + // class MyAttr : Attr { public MyAttr () { } } + // assembly2: + // class Dummy { } + // [assembly:MyAttr()] + // + // the important bit is that we pass the ConstructorBuilder to the CustomAttributeBuilder + var assemblyName1 = new AssemblyName ("Repro55681-2a"); + var assemblyBuilder1 = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName1, AssemblyBuilderAccess.Save, tempDir); + var moduleBuilder1 = assemblyBuilder1.DefineDynamicModule ("Repro55681-2a", "Repro55681-2a.dll"); + var typeBuilder1 = moduleBuilder1.DefineType ("MyAttr", TypeAttributes.Public, typeof (Attribute)); + ConstructorBuilder ctor = typeBuilder1.DefineDefaultConstructor (MethodAttributes.Public); + typeBuilder1.CreateType (); + + var assemblyName2 = new AssemblyName ("Repro55681-2b"); + var assemblyBuilder2 = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName2, AssemblyBuilderAccess.Save, tempDir); + var moduleBuilder2 = assemblyBuilder2.DefineDynamicModule ("Repro55681-2b", "Repro55681-2b.dll"); + + var typeBuilder2 = moduleBuilder2.DefineType ("Dummy", TypeAttributes.Public); + typeBuilder2.DefineDefaultConstructor (MethodAttributes.Public); + typeBuilder2.CreateType (); + + assemblyBuilder2.SetCustomAttribute (new CustomAttributeBuilder (ctor, new object [] { })); + + assemblyBuilder2.Save ("Repro55681-2b.dll"); + assemblyBuilder1.Save ("Repro55681-2a.dll"); + } + } } diff --git a/mono/metadata/sre-internals.h b/mono/metadata/sre-internals.h index 3d7f3b71084..e179c76303a 100644 --- a/mono/metadata/sre-internals.h +++ b/mono/metadata/sre-internals.h @@ -137,5 +137,8 @@ mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflecti guint32 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error); +guint32 +mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec); + #endif /* __MONO_METADATA_SRE_INTERNALS_H__ */ diff --git a/mono/metadata/sre-save.c b/mono/metadata/sre-save.c index 20d9e47a4a3..f430028e861 100644 --- a/mono/metadata/sre-save.c +++ b/mono/metadata/sre-save.c @@ -218,8 +218,18 @@ mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, Mo for (i = 0; i < count; ++i) { cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i); values [MONO_CUSTOM_ATTR_PARENT] = idx; - token = image_create_token_raw (assembly, (MonoObject*)cattr->ctor, FALSE, FALSE, error); /* FIXME use handles */ - if (!mono_error_ok (error)) goto fail; + g_assert (cattr->ctor != NULL); + if (mono_is_sre_ctor_builder (mono_object_class (cattr->ctor))) { + MonoReflectionCtorBuilder *ctor = (MonoReflectionCtorBuilder*)cattr->ctor; + MonoMethod *method = ctor->mhandle; + if (method->klass->image == &assembly->image) + token = MONO_TOKEN_METHOD_DEF | ((MonoReflectionCtorBuilder*)cattr->ctor)->table_idx; + else + token = mono_image_get_methodref_token (assembly, method, FALSE); + } else { + token = image_create_token_raw (assembly, (MonoObject*)cattr->ctor, FALSE, FALSE, error); /* FIXME use handles */ + if (!mono_error_ok (error)) goto fail; + } type = mono_metadata_token_index (token); type <<= MONO_CUSTOM_ATTR_TYPE_BITS; switch (mono_metadata_token_table (token)) { diff --git a/mono/metadata/sre.c b/mono/metadata/sre.c index 276dd704cf9..7811483ae97 100644 --- a/mono/metadata/sre.c +++ b/mono/metadata/sre.c @@ -42,7 +42,6 @@ static GENERATE_GET_CLASS_WITH_CACHE (module_builder, "System.Reflection.Emit", static char* string_to_utf8_image_raw (MonoImage *image, MonoString *s, MonoError *error); #ifndef DISABLE_REFLECTION_EMIT -static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec); static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error); static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error); static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb); @@ -640,7 +639,7 @@ mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, cons } -static guint32 +guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec) { MONO_REQ_GC_NEUTRAL_MODE; @@ -721,6 +720,14 @@ mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 origina return token; } +#else /* DISABLE_REFLECTION_EMIT */ + +guint32 +mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec) +{ + g_assert_not_reached (); + return -1; +} #endif static gboolean |